title: How to read the same file byte by byte asynchronously from within a few threads?
body: <p>I am trying to read a file with aio.h byte by byte using aio_read with a number of threads. But I don't know if I am on the right track since there are not so many stuff to read on the Internet.</p>
  
  <p>I have just created a <code>worker</code> function to pass it to my threads. And also as an argument to pass to the thread, I created a struct called <code>thread_arguments</code> and I pass a few necessary arguments in it, which will be needed for <code>aiocb</code> such as <code>offset</code>, <code>file_path</code> to open, <code>buffer size</code>, and <code>priority</code>.</p>
  
  <p>I can read a file with one thread from start to end successfully. But when it comes to reading a file as chunks from within a few threads, I couldn't make it. And I am not even sure if I can do that with <code>aio-&gt;reqprio</code> without using semaphores or mutexes. (Trying to open a file from within a few threads at the same time?)</p>
  
  <p>How can I read a few number of bytes from within a few threads asynchronously? </p>
  
  <p>Let's say the file contains "foobarquax" and we have three threads using aio library.</p>
  
  <p>Then first one should read "foo", </p>
  
  <p>the second should read "bar" and</p>
  
  <p>the last one should read "quax" asynchronously.</p>
  
  <p>You can see screenshots of issues regarding running it with multiple threads <a href="https://imgur.com/a/iIYH6QT" rel="nofollow noreferrer">on here</a> </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;aio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;fcntl.h&gt; // open -&gt; file descriptor O_RDONLY, O_WRONLY, O_RDWR
  #include &lt;errno.h&gt;
  #include &lt;unistd.h&gt;
  
  typedef struct thread_args {
      char *source_path;
      char *destination_path;
      long int buffer_size;
      long int buffer_size_last; // buffer size for the last thread in case there is a remainder.
      long int offset;
      int priority;
  } t_args;
  
  
  void *worker(void *thread_args) {
  
  
      t_args *arguments = (t_args *) thread_args;
  
  
      struct aiocb *aiocbRead;
  
      aiocbRead = calloc(1, sizeof(struct aiocb));
  
      aiocbRead-&gt;aio_fildes = open(arguments-&gt;source_path, O_RDONLY);
  
      if (aiocbRead-&gt;aio_fildes == -1) {
          printf("Error");
  
      }
  
      printf("opened on descriptor %d\n", aiocbRead-&gt;aio_fildes);
  
      aiocbRead-&gt;aio_buf = malloc(sizeof(arguments-&gt;buffer_size));
      aiocbRead-&gt;aio_offset = arguments-&gt;offset;
      aiocbRead-&gt;aio_nbytes = (size_t) arguments-&gt;buffer_size;
      aiocbRead-&gt;aio_reqprio = arguments-&gt;priority;
  
      int s = aio_read(aiocbRead);
  
      if (s == -1) {
          printf("There was an error");
      }
  
      while (aio_error(aiocbRead) == EINPROGRESS) {}
  
      printf("Bytes read %ld", aio_return(aiocbRead));
  
      close(aiocbRead-&gt;aio_fildes);
  
      for (int i = 0; i &lt; arguments-&gt;buffer_size ; ++i) {
          printf("%c\n", (*((char *) aiocbRead-&gt;aio_buf + i)));
      }
  }
  
  // Returns a random alphabetic character
  char getrandomChar() {
  
  
      int letterTypeFlag = (rand() % 2);
  
      if (letterTypeFlag)
          return (char) ('a' + (rand() % 26));
      else
          return (char) ('A' + (rand() % 26));
  }
  
  void createRandomFile(char *source, int numberofBytes) {
  
      FILE *fp = fopen(source, "w");
  
      for (int i = 0; i &lt; numberofBytes; i++) {
          fprintf(fp, "%c", getrandomChar());
      }
  
      fclose(fp);
  
  }
  
  int main(int argc, char *argv[]) {
  
      char *source_path = argv[1];
      char *destination_path = argv[2];
      long int nthreads = strtol(argv[3], NULL, 10);
  
  
      // Set the seed.
      srand(time(NULL));
  
      // Get random number of bytes to write to create the random file.
      int numberofBytes = 10 + (rand() % 100000001);
  
      // Create a random filled file at the source path.
      createRandomFile(source_path, 100);
  
      // Calculate the payload for each thread.
      long int payload = 100 / nthreads;
      long int payloadLast = payload + 100 % nthreads;
  
      // Create a thread argument to pass to pthread.
      t_args *thread_arguments = (t_args *) malloc(nthreads * sizeof(t_args));
  
      for (int l = 0; l &lt; nthreads; ++l) {
  
          // Set arguments in the struct.
          (&amp;thread_arguments)[l]-&gt;source_path = source_path;
          (&amp;thread_arguments)[l]-&gt;destination_path = destination_path;
          (&amp;thread_arguments)[l]-&gt;buffer_size = payload;
          (&amp;thread_arguments)[l]-&gt;buffer_size_last = payloadLast;
          (&amp;thread_arguments)[l]-&gt;offset = l * payload;
          (&amp;thread_arguments)[l]-&gt;priority = l;
  
      }
  
  
      pthread_t tID[nthreads];
  
      // Create pthreads.
      for (int i = 0; i &lt; nthreads; ++i) {
          pthread_create(&amp;tID[i], NULL, worker, (void *) &amp;thread_arguments[i]);
      }
  
      // Wait for pthreads to be done.
      for (int j = 0; j &lt; nthreads; ++j) {
          pthread_join(tID[j], NULL);
      }
  
      free(thread_arguments);
  
      return 0;
  }
  </code></pre>
  
  <p>This code is reading succesfully if I just call it from one thread but doesn't work if I use it for more than one threads which is what I want.</p>