免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3639 | 回复: 2
打印 上一主题 下一主题

[原创]Linux多线程编程中Thread-Specific Data(线程相关的数据)用处与用法 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-05-28 20:43 |只看该作者 |倒序浏览
Linux多线程编程中引入了Thread-Specific Data(线程相关的数据)的概念
为什么需要"线程相关的数据"呢?怎样使用"线程相关的数据"呢?

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

这里只介绍我个人认为的一个原因, 当然它还有许多其他用途,欢迎大家讨论

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

(下面的例子与实现只是为了说明问题,有些地方可能不妥)

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

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

  1. #include <string.h>
  2. #include <pthread.h>
  3. #define MAXLENGTH 20

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

  8. void * thread_func (void * args)
  9. {
  10.   char threadName[MAXLENGTH];
  11.   strncpy (threadName, (char *)args, MAXLENGTH-1);
  12.   
  13.   printf ("%s is running in thread_func\n", threadName);
  14.   another_func (threadName);
  15.   
  16. }

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

  19.   pthread_t pa, pb;
  20.   pthread_create ( &pa, NULL, thread_func, "Thread A");
  21.   pthread_create ( &pb, NULL, thread_func, "Thread B");

  22.   pthread_join (pa, NULL);
  23.   pthread_join (pb, NULL);
  24. }
复制代码


输出结果为:
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. 使用全局变量

  1. #include <string.h>
  2. #include <pthread.h>
  3. #define MAXLENGTH 20

  4. char threadName[MAXLENGTH];
  5. pthread_mutex_t sharedMutex=PTHREAD_MUTEX_INITIALIZER;

  6. void another_func ()
  7. {
  8.   printf ("%s is running in another_func\n", threadName);
  9. }

  10. void * thread_func (void * args)
  11. {
  12.   pthread_mutex_lock(&sharedMutex);
  13.   strncpy (threadName, (char *)args, MAXLENGTH-1);
  14.   printf ("%s is running in thread_func\n", threadName);
  15.   another_func ();
  16.   pthread_mutex_unlock(&sharedMutex);
  17.   
  18. }

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

  21.   pthread_t pa, pb;
  22.   pthread_create ( &pa, NULL, thread_func, "Thread A");
  23.   pthread_create ( &pb, NULL, thread_func, "Thread B");

  24.   pthread_join (pa, NULL);
  25.   pthread_join (pb, NULL);
  26. }
复制代码

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

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


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

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

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

  3. pthread_key_t p_key;

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

  8. void * thread_func (void * args)
  9. {
  10.   pthread_setspecific(p_key, args);
  11.   printf ("%s is running in thread_func\n", (char *)pthread_getspecific(p_key));
  12.   another_func ();
  13.   
  14. }

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

  17.   pthread_t pa, pb;

  18.   pthread_key_create(&p_key, NULL);
  19.   
  20.   pthread_create ( &pa, NULL, thread_func, "Thread A");
  21.   pthread_create ( &pb, NULL, thread_func, "Thread B");

  22.   pthread_join (pa, NULL);
  23.   pthread_join (pb, NULL);
  24. }
复制代码


说明:
(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存取的数据是相互独立的,
这样就不需要额外的互斥机制来保证数据访问的正确性了.

[ 本帖最后由 ypxing 于 2007-8-9 14:54 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-05-29 08:49 |只看该作者
难道发错版了?

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
3 [报告]
发表于 2007-05-29 11:07 |只看该作者
强烈顶
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP