在 单线程的程序里,有两种基本的数据:全局变量和局部变量。但在多线程程序里,还
有第三种数据类型:线程数据(TSD: Thread-Specific Data)。它和全局变量很象,在线程
内部,各个函数可以象使用全局变量一样调用它,但它对线程外部的其它线程是不可见
的。这种数据的必要性是显而易见 的。例如我们常见的变量 errno,它返回标准的出错信
息。
它显然不能是一个局部变量,几乎每个函数都应该可以调用它;但它又不能是一个全
局变量,否则在 A 线程里输出的很可能是 B 线程的出错信息。要实现诸如此类的变量,
我们就必须使用线程数据。
我们为每个线程数据创建一个键,它和这个键相关联,在各个
线程 里,都使用这个键来指代线程数据,但在不同的线程里,这个键代表的数据是不同
的,在同一个线程里,它代表同样的数据内容。
下面的多线程程序在 Red Hat9 上的测试通过的线程私有的全局变量使用的例子。
为了简便
起见,省去了所有的错误处理代码。其中的变量 no 是线程私有变量,就相当于线程内部
的全局变量,可以看到,对 no 的访问不 能通过 no 本身变量去访问,而是通过一个全局
变量 key 间接的去访问。
从程序运行时的输出可以发现:线程可以在任何函数中访问 no;
线程拥有各自的 no 存 储空间。
#include<pthread.h>;
#include<stdio.h>;
pthread_key_t key;
void start();
void work();
int main()
{
pthread_t tid1,tid2;
pthread_key_create( &key, NULL );
pthread_create( &tid1,NULL,(void *)start,NULL );
pthread_create( &tid2,NULL,(void *)start,NULL );
pthread_join( tid1,NULL );
pthread_join( tid2,NULL );
pthread_key_delete( key );
}
void start()
{
int no;
pthread_setspecific( key, &no );
work();
}
void work(){
int *p_no,i;
for( i=0;i<20;i++ ){
p_no = pthread_getspecific( key );
printf( "%d:%d\n", pthread_self(), *p_no );
*p_no = *p_no+1;
pthread_setspecific( key, p_no );
sleep(1);
}
}
说明:
(1)
线程 1, 2 共用了 key,
通过 key,就可以存取只跟当前线程相关的一个值(这个值由编译器管理)
线程 1----->key----->线程 1 相关的值(由编译器管理)
线程 2----->key----->线程 2 相关的值(由编译器管理)
设置"线程相关的数据",使用
int pthread_setspecific(pthread_key_t key, const void *pointer);
读取"线程相关的数据",使用
void * pthread_getspecific(pthread_key_t key);
注意到,这两个函数分别有一个 void 类型的指针,我们的线程就是通过这两个指针分别与
"线程相关的数据"的数据进行交互的
(2)
由于 key 是一个全局变量,
函数 work 不需要额外的参数就可以访问它;
又因为它是"线程相关的数据", 线程 1, 2 通过 key 存取的数据是相互独立的,
这样就不需要额外的互斥机制来保证数据访问的正确性了.
摘自:http://www.xuebuyuan.com/2047005.html
多线程内的全局变量(私有数据) :
多线程环境下的私有数据(Thread-specific Data, TSD):
线程拥有自己的全局变量,这种特殊的变量仅在某个线程内部有效。线程的私有数据可以被其内部的所有函数访问,但是对其他线程是屏蔽的。线程私有数据采用了一种称为一键多值的技术,即一个键对应多个数值。访问数据时都是通过键值来访问,好像是对一个变量进行访问,其实是在访问不同的数据。
操作线程私有数据的函数主要有4个:
pthread_key_create(创建一个键),pthread_setspecific(为一个键设置线程私有数据),pthread_getspecific(从一个键读取线程私有数据),pthread_key_delete(删除一个键)。
#include <pthread.h>
int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *));
int pthread_setspecific(pthread_key_t key, const void * pointer);
void* pthread_getspecific(pthread_key_t key);
int pthread_key_delete(pthread_key_t key);
来自:http://xsh8637.blog.163.com/blog/static/24099666201032125010616/
linux下C语言多线程(二)线程的私有数据:
http://blog.csdn.net/zjl410091917/article/details/8000926
作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/7589/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
最后编辑: jackxiang 编辑于2014-10-28 10:19
评论列表