title: Semaphores and threads in C
body: <p>Program should take 3 filenames as parameters, create 2 threads, first thread reads from first file, second thread reads from second file, and they both write to the third file. Ultimately they should alternate writing each line from the file they are reading to the third file. When I run the program they don't really alternate; sometimes one thread writes all its lines to the file, then the other writes all of it's lines to the file. Sometimes they alternate for one line each, then a couple for one thread, then a couple for the other. Can someone point me in the write direction to get each thread to alternate writing to the file? I find that when I change the 3rd parameter for the sem_init function it affects the way the threads alternate.</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;semaphore.h&gt;
  #include &lt;errno.h&gt;
  
  
  #define BADFILE  2
  #define BADPARAM 3
  #define DEBUG    1
  
  sem_t mutex;
  
  typedef struct {
      char *file;
      FILE *mf;
  } read_args;
  
  void error(char *msg, int code)
  {
      fprintf(stderr, "Error: %s\nAborting.\n", msg);
      exit(code);
  }
  
  void *readFile1(void *p)
  {
  
      read_args *param = (read_args *)p;
      FILE *f1;
      char *line;
      size_t len = 0;
      ssize_t read;
      int lineCount = 1;
      f1 = fopen(param-&gt;file, "r");
      if(f1 == NULL)
      {
          error("File not found.", BADFILE);
      }
  
  
      while((read = getline(&amp;line, &amp;len, f1)) != -1)
      {  
          sem_wait(&amp;mutex);
          fprintf(param-&gt;mf,"%s: %d: %s", param-&gt;file, lineCount,line);
  
  #if DEBUG        
          printf("%s: %d: %s", param-&gt;file, lineCount,line);
  #endif 
  
          sem_post(&amp;mutex);
          lineCount++;
      } 
      fclose(f1);
      pthread_exit(NULL);
  }
  
  void *readFile2(void *p)
  {
  
      read_args *param = (read_args *)p;
      FILE *f1;
      char *line;
      size_t len = 0;
      ssize_t read;
      int lineCount = 1;
      f1 = fopen(param-&gt;file, "r");
      if(f1 == NULL)
      {
          error("File not found.", BADFILE);
      }
      //sem_wait(&amp;mutex);
      while((read = getline(&amp;line, &amp;len, f1)) != -1)
      {  
          sem_wait(&amp;mutex);
          fprintf(param-&gt;mf,"%s: %d: %s", param-&gt;file, lineCount,line);
  
  #if DEBUG        
          printf("%s: %d: %s", param-&gt;file, lineCount,line);
  #endif 
  
          sem_post(&amp;mutex);
          lineCount++;
      }
  
      fclose(f1);
      pthread_exit(NULL);
  }
  
  
  int main(int argc, char **argv)
  {
      FILE *f;
      char *mergedfile;
      pthread_t tid1, tid2;
      read_args *p1;
      read_args *p2;
      p1 = malloc(sizeof(read_args));
      p2 = malloc(sizeof(read_args));
      if(argc != 4)
      {
          error("Invalid parameters. Proper use: ./merge &lt;file1&gt; &lt;file2&gt;" 
              " &lt;mergedfile&gt;", BADPARAM);
      }
  
      p1-&gt;file = argv[1];
      p2-&gt;file = argv[2];
  
      mergedfile = argv[3];
      f = fopen(mergedfile, "w");
      if(f == NULL)
      {
          error("Can't open file.", BADFILE);
      }
      p1-&gt;mf = f;
      p2-&gt;mf = f;
  
      sem_init(&amp;mutex, 0, 3);
      if(pthread_create(&amp;tid1, NULL, readFile1, (void*)p1) &lt; 0)
      {
          error("Can't create first thread", EXIT_FAILURE);
      }
      if(pthread_create(&amp;tid2, NULL, readFile2, (void*)p2) &lt; 0)
      {
          error("Can't create second thread", EXIT_FAILURE);
      }
      if(pthread_join(tid1, NULL) &lt; 0)
      {
          error("Can't join first thread", EXIT_FAILURE);
      }
      if(pthread_join(tid2, NULL) &lt; 0)
      {
          error("Can't join second thread", EXIT_FAILURE);
      }
      sem_destroy(&amp;mutex);
  
      fclose(f);
      return(EXIT_SUCCESS);
  
  }
  </code></pre>