С pthread_key_create
manpage:
Дополнительная функция деструктора может
быть связаны с каждым значением ключа. В
выход из потока, если значение ключа имеет
ненулевой указатель деструктора и
поток имеет ненулевое значение
с помощью клавиши функция указывает на
вызывается с текущим связанным
ценность в качестве единственного аргумента.
порядок вызовов деструкторов
не указано, если более одного
деструктор существует для потока, когда
это выходит.
Если после всех деструкторов есть
был вызван для всех ненулевых значений
с соответствующими деструкторами, есть
все еще некоторые ненулевые значения с
связанные деструкторы, то
Процесс повторяется. Если после
минимум [PTHREAD_DESTRUCTOR_ITERATIONS]
итерации деструктора
выдающиеся ненулевые значения, там
все еще некоторые ненулевые значения с
связанные деструкторы,
реализация перестает звонить
деструкторов.
Я написал небольшой пример с простым деструктором, печатающим «Hello World» для значения, не относящегося к NULL-потоку. Насколько я могу видеть, этот деструктор вызывается только один раз (по крайней мере, в linux fedora и mac os x), даже если специфическое для потока значение все еще не равно NULL после первого вызова деструктора.
Я что-то пропустил ?! (PTHREAD_DESTRUCTOR_ITERATIONS = 4 для glibc.)
Вот мой маленький пример:
#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;
}