When is the pthread_key_create destructor called?

Ross Johnson Ross.Johnson@homemail.com.au
Sun Mar 23 01:51:00 GMT 2008


Brian,

Brian Cole wrote:
> Is it safe to assume that when a thread exits its destructor functions
> for thread specific values have finished executing before the thread
> can be joined?
>   
Yes, pthread_join() waits and continues only after all destructors have 
returned. As described by the manual page and the standard 
(http://www.opengroup.org/onlinepubs/009695399/functions/pthread_key_create.html), 
the library rechecks all keys and their values in case a specific 
destructor needs to be called again. A key will be checked at most 
PTHREAD_DESTRUCTOR_ITERATIONS  (= 4, IIRC) times and if the key value is 
not null by that time the key is forcibly deleted.

> For example, is the following free of race conditions?
> static pthread_key_t key;
>
> void dtor(void *val)
> {
>   // safely push the data pointed to by val into some global data structure
> }
>
> void *thread_func(void *)
> {
>   pthread_setspecific(key, //pointer to some data that will be pushed
> into a global data structure on exit);
>   pthread_exit(NULL); // What happens if I don't call this and let it
> run off the end of the function?
> }
>   
You can let your thread routine run off the end - pthread_exit() is is 
called implicitly in that case.
> int main()
> {
>   pthread_key_create(key, dtor);
>
>   pthread_t thrd;
>   pthread_create(&thrd, NULL, thread_func, NULL);
>
>   void *ret;
>   pthread_join(thrd, &ret);
>
>   // safe to assume data that was in thread local storage is all in my
> global data structure?
> }
>   
It is safe to assume your destructors have been called and returned.
> If this is not the case, would adding a pthread_key_delete achieve the
> desired behavior?
No, pthread_key_delete() removes the key for ALL threads, but does not 
call the destructor for ANY threads. If you think of TSD keys as a two 
dimensional array, with threads across and keys down and each cell as a 
TSD association between a key and a thread. Exiting a thread removes a 
column of TSD associations, deleting a key removes a row of TSD 
associations.
>  And further, how cross-platform is this behavior
> seeing as I can't find it explicitly stated in any pthreads
> documentation.
>   
This is Single Unix Specification (nee POSIX) behaviour. The manual 
pages for each of these routines pretty much reflects the standard 
descriptions. See, for example:-

http://www.opengroup.org/onlinepubs/009695399/toc.htm
(In the left frame, select the "System Interfaces" volume and then 
section 3 "System Interfaces")

Specifically:
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_key_create.html
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_exit.html
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_join.html
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_key_delete.html

> To further complicate the matter my threads are actually OpenMP
> threads. Is it safe to assume they will properly clean up thread
> specific data in the same semantic fashion?
>   
I'm not familiar with OpenMP.
> Thanks,
> Brian
>   

Regards.
Ross



More information about the Pthreads-win32 mailing list