Linux多线程编程中Thread-Specific Data(线程相关的数据)使用详解

wlcy1988 2007-06-06 09:36:49
Linux多线程编程中引入了Thread-Specific Data(线程相关的数据)的概念
为什么需要"线程相关的数据"呢?怎样使用"线程相关的数据"呢?

1. 为什么需要Thread-Specific Data "线程相关的数据"

例子:实现同时运行两个线程,对于每个线程,在该线程调用的每个函数中打印线程的名字,以及它正在调用的函数的名字.

不使用"线程相关的数据"的两种实现方法:

实现方法1. 不使用全局变量

#include <string.h>
#include <pthread.h>
#define MAXLENGTH 20

void another_func (const char * threadName)
{
printf ("%s is running in another_func\n", threadName);
}

void * thread_func (void * args)
{
char threadName[MAXLENGTH];
strncpy (threadName, (char *)args, MAXLENGTH-1);

printf ("%s is running in thread_func\n", threadName);
another_func (threadName);

}

int main (int argc, char * argv[])
{

pthread_t pa, pb;
pthread_create ( &pa, NULL, thread_func, "Thread A");
pthread_create ( &pb, NULL, thread_func, "Thread B");

pthread_join (pa, NULL);
pthread_join (pb, NULL);
}

输出结果为:
Thread A is running in thread_func
Thread A is running in another_func
Thread B is running in thread_func
Thread B is running in another_func

该方法的缺点是:由于要记录是哪一个线程在调用函数,每个函数需要一个额外的参数来
记录线程的名字,例如another_func函数需要一个threadName参数
如果调用的函数多了,则每一个都需要一个这样的参数

实现方法2. 使用全局变量

#include <string.h>
#include <pthread.h>
#define MAXLENGTH 20

char threadName[MAXLENGTH];
pthread_mutex_t sharedMutex=PTHREAD_MUTEX_INITIALIZER;

void another_func ()
{
printf ("%s is running in another_func\n", threadName);
}

void * thread_func (void * args)
{
pthread_mutex_lock(&sharedMutex);
strncpy (threadName, (char *)args, MAXLENGTH-1);
printf ("%s is running in thread_func\n", threadName);
another_func ();
pthread_mutex_unlock(&sharedMutex);

}

int main (int argc, char * argv[])
{

pthread_t pa, pb;
pthread_create ( &pa, NULL, thread_func, "Thread A");
pthread_create ( &pb, NULL, thread_func, "Thread B");

pthread_join (pa, NULL);
pthread_join (pb, NULL);
}

该方法的缺点是:由于多个线程需要读写全局变量threadName,就需要使用互斥机制

分析以上两种实现方法,Thread-Specific Data "线程相关的数据"的一个好处就体现出来了:
(1)"线程相关的数据"可以是一个全局变量,并且
(2)每个线程存取的"线程相关的数据"是相互独立的.


2. 怎样使用"线程相关的数据"

这是利用"线程相关的数据"的实现方式:

#include <string.h>
#include <pthread.h>

pthread_key_t p_key;

void another_func ()
{
printf ("%s is running in another_func\n", (char *)pthread_getspecific(p_key));
}

void * thread_func (void * args)
{
pthread_setspecific(p_key, args);
printf ("%s is running in thread_func\n", (char *)pthread_getspecific(p_key));
another_func ();

}

int main (int argc, char * argv[])
{

pthread_t pa, pb;

pthread_key_create(&p_key, NULL);

pthread_create ( &pa, NULL, thread_func, "Thread A");
pthread_create ( &pb, NULL, thread_func, "Thread B");

pthread_join (pa, NULL);
pthread_join (pb, NULL);
}


说明:
(1)
线程A, B共用了p_key,
通过p_key,就可以存取只跟当前线程相关的一个值(这个值由编译器管理)
线程A----->p_key----->线程A相关的值(由编译器管理)
线程B----->p_key----->线程B相关的值(由编译器管理)

设置"线程相关的数据",使用
int pthread_setspecific(pthread_key_t key, const void *pointer);
读取"线程相关的数据",使用
void * pthread_getspecific(pthread_key_t key);

注意到,这两个函数分别有一个void类型的指针,我们的线程就是通过这两个指针分别与
"线程相关的数据"的数据进行交互的

(2)
由于p_key是一个全局变量,
函数another_func不需要额外的参数就可以访问它;
又因为它是"线程相关的数据", 线程A, B通过p_key存取的数据是相互独立的,
这样就不需要额外的互斥机制来保证数据访问的正确性了.
--
我们能做的事情很多,唯一受限制的是我们的
创造力和想象力
...全文
770 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
laxila 2008-09-30
  • 打赏
  • 举报
回复
非常好,学习过了,谢谢楼主呀!!!
majiajun_no_5 2008-09-30
  • 打赏
  • 举报
回复
获益匪浅
majiajun_no_2 2008-09-29
  • 打赏
  • 举报
回复
潜水多年,今日上岸,继续学习。
majiajun_no_13 2008-09-28
  • 打赏
  • 举报
回复
快乐顶贴,快乐看贴,快乐学习
converf 2008-09-25
  • 打赏
  • 举报
回复
分析得精彩.....
很受益!
laxila 2008-09-25
  • 打赏
  • 举报
回复
留脚印
wzzwt 2008-09-23
  • 打赏
  • 举报
回复
支持下
chinaren_xf 2008-08-28
  • 打赏
  • 举报
回复
mark,学到的东西不少,虽然我看到的比较晚,m`~~~~~~~a ~~~~~~r~~~~k
michaelxuyw 2007-06-12
  • 打赏
  • 举报
回复
mark

568

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧