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
",(char *)arg);
	key = 10;
	printf("key=%d, the child id is %lu
", key, pthread_self());
	
	return NULL;
}

void *helloworld_two(void *arg)
{
	printf("the message is %s
", (char *)arg);
	sleep(1);
	printf("key=%d, the child id is %lu
", 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
", pthread_self(), t); 
} 

void *child1(void *arg) 
{ 
	int i = 10;
	
	pthread_t tid = pthread_self(); //线程号
	printf("
set key value %d in thread %lu
", i, tid); 
	
	pthread_setspecific(key, &i); // 设置私有数据
	
	printf("thread one sleep 2 until thread two finish

");
	sleep(2); 
	printf("
thread %lu returns %d, add is %p
",
		tid, *((int *)pthread_getspecific(key)), pthread_getspecific(key) ); 
} 

void *child2(void *arg) 
{ 
	int temp = 20;
	
	pthread_t tid = pthread_self();  //线程号
	printf("
set key value %d in thread %lu
", temp, tid); 
	
	pthread_setspecific(key, &temp); //设置私有数据
	
	sleep(1); 
	printf("thread %lu returns %d, add is %p
", 
		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
查看评论
* 以上用户言论仅仅代表其个人观点。不代表CSDN站点的观点或立场

unix/linux下线程私有数据实现原理及用法

复习曾经做过的爬虫系统,在做防止死链时用到了线程的私有数据,那时候不过会用,至于底层是怎么实现的以及为什么一个键能够相应不同线程的指还一知半解。今天又具体的看了下相关的资料,以做总结。      ...
  • caigen1988
  • caigen1988
  • 2012-08-23 20:30
  • 6482

线程私有数据STD

http://blog.csdn.net/xluren/article/details/8226668 下面来自:http://www.ibm.com/developerworks/cn/lin...
  • u013074465
  • u013074465
  • 2015-05-16 15:20
  • 1646

线程私有数据

在多线程程序中,常常要用全局变量来实现多个函数间的数据共享。因为数据空间是共享的,因此全局变量也为全部线程共同拥有。

測试代码例如以下: [cpp] view pl...

  • lianghe_work
  • lianghe_work
  • 2015-08-18 09:45
  • 1614

linux线程私有数据具体解释

在单线程程序中,函数常常使用全局变量或静态变量,这是不会影响程序的正确性的,但假设线程调用的函数使用全局变量或静态变量,则非常可能引起编程错误,由于这些函数使用的全局变量和静态变量无法为不同的线程保存各...
  • caoyan_12727
  • caoyan_12727
  • 2016-08-22 22:07
  • 1373

Linux线程私有数据pthread_key_t

转至:http://blog.163.com/william_djj@126/blog/static/3516650120085111193035/ *------------------------...
  • xiaohuangcat
  • xiaohuangcat
  • 2014-01-14 17:16
  • 4171

linux线程私有数据具体解释

在单线程程序中,函数常常使用全局变量或静态变量,这是不会影响程序的正确性的,但假设线程调用的函数使用全局变量或静态变量,则非常可能引起编程错误,由于这些函数使用的全局变量和静态变量无法为不同的线程保存各...
  • caoyan_12727
  • caoyan_12727
  • 2016-08-22 22:07
  • 1373

Linux系统编程——线程私有数据

在多线程程序中,常常要用全局变量来实现多个函数间的数据共享。

因为数据空间是共享的,因此全局变量也为全部线程共同拥有。

但有时应用程序设计中必要提供线程私有的全局变量。这个变量仅在线程中有效,但却能够跨过多...

  • tennysonsky
  • tennysonsky
  • 2015-06-11 14:36
  • 1369

【Linux系统编程】线程私有数据

在多线程程序中,常常要用全局变量来实现多个函数间的数据共享。因为数据空间是共享的,因此全局变量也为全部线程共同拥有。

測试代码例如以下: [cpp] view plain copy  ...

  • dengjin20104042056
  • dengjin20104042056
  • 2016-08-08 22:45
  • 458

Linux系统编程——进程和线程的差别与联系

假设说进程是一个资源管家,负责从主人那里要资源的话,那么线程就是干活的苦力。一个管家必须完毕一项工作,就须要最少一个苦力,也就是说,一个进程最少包括一个线程,也能够包括多个线程。

苦力要干活,就须要依托...

  • tennysonsky
  • tennysonsky
  • 2015-05-27 14:48
  • 3327

Linux系统编程(27)——线程控制

进程在各自独立的地址空间中运行。进程之间共享数据须要用mmap或者进程间通信机制,那么怎样在一个进程的地址空间中运行多个线程呢。有些情况须要在一个进程中同一时候运行多个控制流程,这时候线程就派上了用场。比...
  • yincheng01
  • yincheng01
  • 2014-09-04 00:51
  • 912
    个人资料
    • 訪问:632411次
    • 积分:10548
    • 等级:
    • 排名:第1810名
    • 原创:256篇
    • 转载:68篇
    • 译文:9篇
    • 评论:280条
    相关声明
    博客专栏
    最新评论
【推广】 免费学中医,健康全家人
原文地址:https://www.cnblogs.com/llguanli/p/8260802.html