cpointerspthreadspass-by-valuepointer-to-pointer

Why the second argument to pthread_join() is a **, a pointer to a pointer?


I am new to using pthread and also not that familiar with pointers to pointers. Could somebody perhaps explain why the second argument of pthread_join() is a void **. Why is it designed like this.

int pthread_join(pthread_t thread, void **value_ptr);

Solution

  • To return a value via a function's argument you need to pass in the address of the variable to receive the new value.

    As pthread_join() is designed to receive the pointer value being passed to pthread_exit(), which is a void*, pthread_join() expects the address of a void* which in fact is of type void**.

    Example:

    #include <stdlib.h> /* for EXIT_xxx macros */
    #include <stdio.h> /* for printf() and perror() */
    #include <pthread.h> 
    
    void * tf(void * pv)
    {
      int * a = pv;
      size_t index = 0;
    
      printf("tf(): a[%zu] = %d\n", index , a[index]);
    
      ++index;
    
      pthread_exit(a + index); /* Return from tf() the address of a's 2nd element. 
                              a + 1 here is equivalent to &a[1]. */
    }
    
    
    int main(void)
    {
      int a[2] = {42, 43};
      pthread_t pt;
      int result = pthread_create(&pt, NULL, tf, a); /* Pass to tf() the address of 
                                                        a's 1st element. a decays to 
                                                        something equivalent to &a[0]. */
      if (0 != result)
      {
        perror("pthread_create() failed");
        exit(EXIT_FAILURE);
      }
    
      {
        int * pi;
        size_t index = 0;
    
        {
          void * pv;
          result = pthread_join(pt, &pv); /* Pass in the address of a pointer-variable 
                                             pointing to where the value passed to 
                                             pthread_exit() should be written. */
          if (0 != result) 
          {
            perror("pthread_join() failed");
            exit(EXIT_FAILURE);
          }
    
          pi = pv;
        }
    
        ++index;
    
        printf("main(): a[%zu] = %d\n", index, pi[0]);
      }
    
      return EXIT_SUCCESS;
    }
    

    The program above is expected to print:

    tf(): a[0] = 42
    main(): a[1] = 43