11.9 线程私有数据


   引入线程之后就必须重新考虑变量作用域的问题。 在引入线程之前有全局变量和局部变量,但在多个线程情况下,如果将线程当做一个单独实体就多出了一个作用域,就是相对于线程的全局变量,这种变量称为线程私有数据。 每个线程私有数据对应一个键,通过这个键来获取对线程私有数据的访问权。 如果没有这个线程私有数据,线程里每个函数都必须将这个对象作为参数传入,何其繁琐。

int   pthread_key_create(pthread_key_t* key, void (*destructor)(void*));
int   pthread_key_delete(pthread_key_t* key);
void* pthread_getspecific(pthread_key_t key);
int   pthread_setspecific(pthread_key_t key, const void* value);

   创建的键存放在 key 指向的内存单元,这个键可以被所有线程使用,但是不同线程将这个键关联到不同的线程私有数据上。 每个创建的键都设置了一个析构函数,如果为 NULL 那么析构函数不调用。 当线程调用 pthread_exit 或是线程执行返回时析构函数才会调用。 key_delete 只是释放 key 这个内存,并不会调用析构函数。

   线程对创建的键的数量是存在限制的,可以通过 PTHREAD_KEYS_MAX 来获得。 线程退出时会尝试调用一次析构函数,如果所有键绑定的值都已经释放为 NULL,那么正常,否则还会尝试调用一次析构函数,直到尝试次数为 PTHREAD_DESTRUCTOR_ITERATIONS。