pthread_t pointer as argument of pthread_create

24,912

Solution 1

pthread_t* thr;
pthread_create(thr, NULL, &hello, NULL);

declares a pointer to a pthread_t without allocating storage for it. When you call pthread_create, it'll try writing to *thr. This is at an undefined location and will almost certainly fail.

pthread_t thr;
pthread_t* pntr = &thr;
pthread_create(pntr, NULL, &hello, NULL);

works because you've declare storage (thr on the stack) for a pthread_t.

Note that the second, working, version can be simplified to what is used in your hello program

pthread_t thr;
pthread_create(&thr, NULL, &hello, NULL);

...which declares a pthread_t on the stack then passes a pointer to it into pthread_create.

Solution 2

It is because if you simply declare a pointer, you can't expect it to point to allocated, initialised memory.

When you instead declare a pthread_t it gets allocated its own little block of memory that you can then get the address to with the & operator and pass it to pthread_create.

Share:
24,912
user454322
Author by

user454322

Updated on December 16, 2020

Comments

  • user454322
    user454322 over 3 years

    The first argument of pthread_create is a pthread_t pointer. In the hello program below, if the first argument is a pointer to pthread_t (pthread_t*) instead of a pthread_t (pthread_t) the program ends with Segmentation fault...why?

    I don't remember seeing pthread_t* as the declared type of the first argument of pthread_create.
    And chapter 2 of Butenhof's book Programming with POSIX Threads says:

    To create a thread, you must declare a variable of type pthread_t [not pthread_t*].

    But according to the specification the first argument of pthread_create is a pointer to pthread_t, so why the segmentation fault?



    Segmentation fault
    pthread_t* thr;
    pthread_create(thr, NULL, &hello, NULL);
    



    Runs OK
    pthread_t thr;
    pthread_t* pntr = &thr;
    pthread_create(pntr, NULL, &hello, NULL);
    



    hello program:
    #include <pthread.h>
    #include <stdio.h>
    
    void * 
    hello(void *arg){
      printf("Hello\n");
      pthread_exit(NULL);
    }
    
    int 
    main(int argc, char **argv){
      pthread_t thr = 1;
      pthread_create(&thr, NULL, &hello, NULL);
    
    
    
      pthread_join(thr, NULL);
    
      return 0;
    }
    

    pthread_create prototype:

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
    void *(*start_routine)(void*), void *arg);
    
  • user454322
    user454322 over 11 years
    Ohhh... It is because & allocates space! I couldn't spot such a silly thing. Thanks
  • user454322
    user454322 over 11 years
    Note that the second, working, version can be simplified to as is in the hello program.
  • simonc
    simonc over 11 years
    Oh, yes, I'm afraid I hadn't read that far down the question. I'll update my answer
  • user454322
    user454322 over 11 years
    Right. Without & the pointer is not initialized. Thank you.
  • Admin
    Admin over 11 years
    The & operator takes the address of the pthread_t as a pointer of type pthread_t * and this can then be used to call pthread_create. It doesn't initialise the pointer so much as simply create a valid pointer to an allocated area of memory.
  • user454322
    user454322 over 11 years
    Perhaps I wasn't clear. With initializing the pointer, I meant taking the address of (point to, i.e., assigning the address of thr to pntr) the memory where the pthread_t refers. Note that: just between pthread_t* pntr = &thr; and the call to pthread_create pntr is pointing to UNallocated memory (because thr has not been initialized).
  • Admin
    Admin over 11 years
    pntr is pointing to allocated memory because it points to &thr; thr could very well be uninitialised, though.
  • user454322
    user454322 over 11 years
    I see your point. Then pntr points to &thr which in turn points to unallocated memory... rigth?
  • Admin
    Admin over 11 years
    &thr is the address of (pointer to the data of) thr, which is allocated memory on the stack (automatically allocated for you) created by the variable declaration pthread_t thr;. However, because you are merely declaring thr, it is not initialised which means that both pntr and thr are allocated but only pntr is initialised: It contains the value &thr. In the example that works, nothing is pointing to unallocated memory, which is exactly why it works.
  • user454322
    user454322 over 11 years
    Thanks for the followup. With thr, which is allocated memory on the stack (automatically allocated for you) created by the variable declaration pthread_t thr do you mean that the solely pthread_t thr allocates memory? Before pthread_create what thr is pointing to?