【发布时间】:2009-11-15 07:41:30
【问题描述】:
有人知道(或可以发布)使用线程特定数据的示例吗?我正在寻找解释清楚且易于理解的东西。我有一个全局 char * 变量,我想在几个线程之间共享,我想这就是 C 中线程特定数据机制的用途,对吗?
我是 Linux 用户!
【问题讨论】:
标签: c multithreading pthreads
有人知道(或可以发布)使用线程特定数据的示例吗?我正在寻找解释清楚且易于理解的东西。我有一个全局 char * 变量,我想在几个线程之间共享,我想这就是 C 中线程特定数据机制的用途,对吗?
我是 Linux 用户!
【问题讨论】:
标签: c multithreading pthreads
实际上,线程特定数据适用于您不想在线程之间共享数据的情况——对于线程特定数据,每个线程可以使用相同的变量名,但该变量指的是不同的存储。
使用 gcc,您可以使用 __thread 属性将变量声明为特定于线程的变量。如果您只是尝试使原始类型线程特定,并且您只处理 Linux 和 GCC,那么这是一个可能的解决方案。但是,如果您确实想在各种 unice 之间实现可移植性(一个理想的目标),或者如果您想使复杂的数据类型特定于线程,那么您需要为此使用 UNIX 例程...
它在 UNIX 中的工作方式是在生成任何线程之前使用pthread_key_create,以便创建唯一的变量名。然后使用pthread_setspecific 和pthread_getspecific 修改/访问与密钥关联的数据。 set/get 特定函数的语义是 key 表现为 map 的索引,其中每个线程都有自己的 map,因此从不同的线程执行这些例程会导致访问/修改不同的数据。如果您可以使用地图,则可以使用特定于线程的存储。
显然,完成后,您需要调用适当的例程来清理数据。您可以使用pthread_cleanup_push 安排清理例程以释放与线程特定键关联的任何数据结构,并且当不再使用该键时,您可以使用pthread_key_destroy。
【讨论】:
原始 C 运行时库中的 errno 变量就是一个很好的例子。如果一个进程有两个线程进行系统调用,那么它作为一个共享变量将是非常糟糕的。
线程 1:
int f = open (...); 如果 (f线程 2:
int s = 套接字 (...); 如果 (s想象一下,如果 open 和 socket 几乎同时被调用,两者都以某种方式失败,并且都尝试显示错误号,那么会发生什么混乱!
为了解决这个问题,多线程运行时库使 errno 成为线程特定数据项。
【讨论】:
对您的问题的简短回答是:您无需执行任何操作即可在多个线程之间共享变量。所有的全局变量默认在所有线程之间共享。
当每个线程的变量必须不同时,如果您使用的是符合 ISO-C99 的实现(如 GCC),您只需在变量声明中添加 __thread 存储类关键字,如下所示:
__thread char *variable;
这将指示构建链中的所有层(cc、ld、ld.so、libc.so 和 libpthread.so)以特定于线程的特殊方式操作此变量。
以下编译器支持此语法(参见wikipedia):
【讨论】:
__thread 作为 ISO-C99 标准一部分的参考吗?