C:pthread数据特定的析构函数只调用一次

时间:2009-02-23 10:20:33

标签: c pthreads destructor

来自pthread_key_create联机帮助页:

  

可选的析构函数可以   与每个键值相关联。在   线程退出,如果一个键值有一个   非NULL析构函数指针,和   thread具有关联的非NULL值   用键,函数指向   用当前关联的方法调用   价值作为唯一的论据。该   析构函数调用的顺序是   未指定,如果不止一个   析构函数存在于一个线程时   它会退出。

     

如果,所有的析构函数都有   已被调用所有非NULL值   与相关的析构函数有关   仍然有一些非NULL值   相关的析构函数,然后是   过程重复进行。如果,在之后   至少[PTHREAD_DESTRUCTOR_ITERATIONS]   析构函数的迭代调用   出现非NULL值   仍然是一些非NULL值   相关的析构函数   实施停止呼叫   析构函数。

我写了一个小例子,一个简单的析构函数打印“Hello World”,用于非NULL线程特定值。据我所知,这个析构函数只被调用一次(至少在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;
}

2 个答案:

答案 0 :(得分:3)

似乎没有很多人在这里使用pthread!

所以,再次,我会回答我自己的问题:

只有在析构函数中调用pthread_setspecific,更改键的值时,才会多次调用析构函数。

这是因为在调用析构函数之前,键指针设置为null并且指针被传递给析构函数。因此,如果我们希望键指针不为null,则只需调用其中的pthread_setspecific

答案 1 :(得分:-1)

我不明白这个谜。您只有1个特定于线程的密钥,并且只有1个线程可以设置特定于线程的数据。因此析构函数应该只按预期执行一次。

如果在main()中的pthread_create()之后的某处设置特定于线程的数据,则析构函数将被调用两次 - 一次用于子线程,一次用于与main()相关联的线程。