Linux系统编程——线程私有数据
在多线程程序中。常常要用全局变量来实现多个函数间的数据共享。因为数据空间是共享的,因此全局变量也为全部线程共同拥有。
測试代码例如以下:
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> int key = 100; //全局变量 void *helloworld_one(void *arg) { printf("the message is %s\n",(char *)arg); key = 10; printf("key=%d, the child id is %lu\n", key, pthread_self()); return NULL; } void *helloworld_two(void *arg) { printf("the message is %s\n", (char *)arg); sleep(1); printf("key=%d, the child id is %lu\n", key, pthread_self()); return NULL; } int main(int argc, char *argv[]) { pthread_t thread_id_one; pthread_t thread_id_two; //创建线程 pthread_create(&thread_id_one, NULL, helloworld_one, "helloworld_one"); pthread_create(&thread_id_two, NULL, helloworld_two, "helloworld_two"); //等待线程结束。回收资源 pthread_join(thread_id_one, NULL); pthread_join(thread_id_two, NULL); return 0; }
执行结果例如以下:
由执行结果能够看出,当中一个线程对全局变量的改动将影响到还有一个线程的訪问。
但有时应用程序设计中必要提供线程私有的全局变量,这个变量仅在线程中有效。但却能够跨过多个函数訪问。
比方在程序里可能须要每一个线程维护一个链表。而会使用同样的函数来操作这个链表,最简单的方法就是使用同名而不同变量地址的线程相关数据结构。这种数据结构能够由 Posix 线程库维护,成为线程私有数据 (Thread-specific Data,或称为 TSD)。
以下接口所需头文件:
#include <pthread.h>
1)创建线程私有数据
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
功能:
创建一个类型为 pthread_key_t 类型的私有数据变量( key )。
參数:
key:在分配( malloc )线程私有数据之前,须要创建和线程私有数据相关联的键( key ),这个键的功能是获得对线程私有数据的訪问权。
destructor:清理函数名字( 如:fun )。当线程退出时,假设线程私有数据地址不是非 NULL,此函数会自己主动被调用。
该函数指针能够设成 NULL ,这样系统将调用默认的清理函数。
回调函数其定义例如以下:
void fun(void *arg)
{
// arg 为 key 值
}
返回值:
成功:0
失败:非 0
不论哪个线程调用 pthread_key_create(),所创建的 key 都是全部线程可訪问,但各个线程可依据自己的须要往 key 中填入不同的值,相当于提供了一个同名不同值的变量。
2)注销线程私有数据
int pthread_key_delete(pthread_key_t key);
功能:
注销线程私有数据。
这个函数并不会检查当前是否有线程正使用线程私有数据( key ),也不会调用清理函数 destructor() 。而仅仅是将线程私有数据( key )释放以供下一次调用 pthread_key_create() 使用。
參数:
key:待注销的私有数据。
返回值:
成功:0
失败:非 0
3)设置线程私有数据的关联
int pthread_setspecific(pthread_key_t key, const void *value);
功能:
设置线程私有数据( key ) 和 value 关联,注意,是 value 的值(不是所指的内容)和 key 相关联。
參数:
key:线程私有数据。
value:和 key 相关联的指针。
返回值:
成功:0
失败:非 0
4)读取线程私有数据所关联的值
void *pthread_getspecific(pthread_key_t key);
功能:
读取线程私有数据( key )所关联的值。
參数:
key:线程私有数据。
返回值:
成功:线程私有数据( key )所关联的值。
失败:NULL
演示样例代码例如以下:
// this is the test code for pthread_key #include <stdio.h> #include <pthread.h> pthread_key_t key; // 私有数据。全局变量 void echomsg(void *t) { printf("[destructor] thread_id = %lu, param = %p\n", pthread_self(), t); } void *child1(void *arg) { int i = 10; pthread_t tid = pthread_self(); //线程号 printf("\nset key value %d in thread %lu\n", i, tid); pthread_setspecific(key, &i); // 设置私有数据 printf("thread one sleep 2 until thread two finish\n\n"); sleep(2); printf("\nthread %lu returns %d, add is %p\n", tid, *((int *)pthread_getspecific(key)), pthread_getspecific(key) ); } void *child2(void *arg) { int temp = 20; pthread_t tid = pthread_self(); //线程号 printf("\nset key value %d in thread %lu\n", temp, tid); pthread_setspecific(key, &temp); //设置私有数据 sleep(1); printf("thread %lu returns %d, add is %p\n", tid, *((int *)pthread_getspecific(key)), pthread_getspecific(key)); } int main(void) { pthread_t tid1,tid2; pthread_key_create(&key, echomsg); // 创建 pthread_create(&tid1, NULL, child1, NULL); pthread_create(&tid2, NULL, child2, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_key_delete(key); // 注销 return 0; }
执行结果例如以下:
从执行结果来看。各线程对自己的私有数据操作互不影响。
也就是说。尽管 key 是同名且全局,但訪问的内存空间并非同一个。
本文转自:《Linux高级程序设计》
- 顶
- 5
- 踩
- 0
- 本人录制的视频资源
- 个人资料
- 訪问:632411次
- 积分:10548
- 等级:
- 排名:第1810名
- 原创:256篇
- 转载:68篇
- 译文:9篇
- 评论:280条
- 相关声明
- 文章搜索
- 博客专栏
- 文章分类
- 最新评论
-
Linux系统编程——进程和线程的差别与联系
wsl2216108250: 楼主这句话写得非常棒:“线程自己基本上不拥有系统资源,仅仅拥有一点在执行中不可缺少的资源(如程序计数器,...
-
一步步学习Linux多任务编程
sakura_yuan: 感谢分享
-
Linux系统编程——文件描写叙述符的复制:dup()和dup2()
wanglei19930525: 牛逼!看apue看得我眼冒金星,全然不知道哪边是重点,看这个舒服多了,还易懂。
-
Linux系统编程——线程池
Altair_lbn_la_ahad: 博主您好,有个地方百思不得其解,还望解答。87到91行,是啥意思?多余的任务不是应该在链表里等待吗?...
-
Linux系统编程——线程同步与相互排斥:相互排斥锁
u013082827: @tennysonsky:我測试你的程序,线程1先调用,结果也是线程1的h先出来,终于结果是:h w...
-
Linux网络编程——网络协议入门
masterbee: 通俗易懂,看了瞬间明确了这些关系。打算转载
-
Linux网络编程——多播
daze_scarecrow: 沧海一笑-dj 这个博主盗取你的文章还注明是原创。http://blog.csdn.net/d...
-
一步步学习Linux多任务编程
Leezha: 受用,感谢用心的博主。
-
Linux 网络编程——并发server的三种实现模型
tennysonsky: @suikegui007:须要解锁
-
Qt入门学习——Qt 5 帮助文档的使用
lr2131: 授人以鱼不如授人以渔,赞!