线程私有底据thread-specific
线程私有数据thread-specific设计线程私有数据主要基于一下两点需求: 1.我们希望线程间不需要同步机制就能
线程私有数据thread-specific
设计线程私有数据主要基于一下两点需求:
1.我们希望线程间不需要同步机制就能访问各自的separate数据
2.我们期望由于历史原因以进程为基础设计的接口可以适应多线程环境
为实现线程私有数据POSIX规定了如下接口:
int pthread_key_create(pthread_
key_t *key, void (*destructor)(void*));
这个函数创建一个thread-specific数据的键,由指针key指向,在进程中,它对又有线
程都是可见的。key对应的value是不透明的对象,用于定位(locate)thread-sepcific
数据.和key绑定的values被由pthread_setspecific()函数设定的单个线程维护,生命
期和调用线程相同。
注意:同一个键(key)可以被进程中的所有线程使用,但是每个线程通过这个key取到的线程私有
数据的地址不同。当这个键被创建以后,每个线程私有数据的地址被置为NULL.
系统的线程调度算法使得一些线程可能看见一个键值,相反另一些线程却可能看到不同的键
值。这是一种竞争状态,我们可以通过pthread_once解决这个问题。
原型如下:
int pthread_once(pthread_once_t *once_control,
void (*init_routine)(void));
pthread_once_t once_control = PTHREAD_ONCE_INIT;
其中once_control必须为非局部变量,并且被初始化为PTHREAD_ONCE_INIT pthread_once机制如下:
操作系统保证每个线程调用pthread_once时初始化例程init_routine仅在第一次调用
pthread_once被调用一次.避免竞争的正确的key创建方法如下: void destructor(void *);
pthread_key_t key;
pthread_once_t init_done = PTHREAD_ONCE_INIT;
void
thread_init(void)
{
err = pthread_key_create(&key, destructor);
} int
threadfunc(void *arg)
{
pthread_once(&init_done, thread_init);
...
}
一旦key创建成功,我们可以调用pthread_setspecific()为key绑定线程私有数据.通过
pthread_getspecific可以得到线程私有数据的地址
这两个函数的函数原型如下
void *pthread_getspecific(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void *value);