从pthread_key_create
手册页:
可选的析构函数可以与每个键值相关联。在线程退出时,如果键值具有非 NULL 析构函数指针,并且线程具有与键关联的非 NULL 值,则以当前关联值作为其唯一参数调用指向的函数。如果线程退出时存在多个析构函数,则未指定析构函数调用的顺序。
如果在所有非 NULL 值与关联的析构函数调用了所有析构函数之后,仍然有一些非 NULL 值与关联的析构函数,则重复该过程。如果在析构函数的至少 [PTHREAD_DESTRUCTOR_ITERATIONS] 次迭代调用杰出的非 NULL 值之后,仍然有一些非 NULL 值具有关联的析构函数,则实现停止调用析构函数。
我写了一个小例子,用一个简单的析构函数为非 NULL 线程特定值打印“Hello World”。据我所知,这个析构函数只被调用一次(至少在 linux fedora 和 mac os x 上),即使在第一次调用析构函数后线程特定的值仍然不是 NULL。
我错过了什么吗?!(在 glibc 上 PTHREAD_DESTRUCTOR_ITERATIONS = 4。)
这是我的小例子:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NB_THREADS 1
#define NB_KEYS 1
static pthread_key_t keys[NB_KEYS];
static pthread_mutex_t mutex;
void destruction (void *arg)
{
(int) arg ++;
printf ("Destructor called! -- key value : %i\n", (int)arg);
}
void* startup_routine(void* argv)
{
int i;
int th = (int) argv;
for (i = 0; i < NB_KEYS; i++)
pthread_setspecific(keys[i], (void*) ((th + i)* 2));
pthread_mutex_lock(&mutex);
printf("Thread %i\n", th);
for (i = 0; i < NB_KEYS; i++)
printf ("\tkeys[%i] : %i\n", i, (int)pthread_getspecific(keys[i]));
pthread_mutex_unlock(&mutex);
return "End";
}
int main(int argc, char** argv)
{
int i;
void *result;
pthread_t thread[NB_THREADS];
for (i = 0; i < NB_KEYS; i++)
pthread_key_create(&keys[i], destruction);
pthread_mutex_init(&mutex, NULL);
for (i = 0; i < NB_THREADS; i++)
pthread_create( &thread[i], NULL, startup_routine, (void*)(i+1) );
for (i = 0; i < NB_THREADS; i++)
{
pthread_join( thread[i], &result );
printf("Return from the thread %i = '%s'\n", i, (char*)result );
}
return 0;
}