【发布时间】:2010-04-18 14:41:52
【问题描述】:
我在 C 库中有全局静态变量,它们在多线程运行中生成异常。我需要以某种方式使它们安全(即,每个线程应该与这些变量的不同实例相关)。有什么推荐的方法吗?
【问题讨论】:
标签: c multithreading static-variables
我在 C 库中有全局静态变量,它们在多线程运行中生成异常。我需要以某种方式使它们安全(即,每个线程应该与这些变量的不同实例相关)。有什么推荐的方法吗?
【问题讨论】:
标签: c multithreading static-variables
没有适用于所有 C 实现的标准方法,但存在特定于实现的解决方案。例如,使用微软的编译器(参见the docs),
__declspec( thread ) int tls_i = 1;
使tls_i 存在于线程本地存储中(每个线程都有自己独立的此变量实例)。使用gcc,语法为
__thread int tls_i;
您可能还想查看该主题的wikipedia entry。
【讨论】:
__thread 关键字正如我刚刚在我的回答中所说的(我还指出了关于线程本地存储的gcc 文档页面以获取更多详细信息)。
第一个问题:
如果您需要前者,其他答案已对“线程本地存储”提出了建议。
如果您需要后者,那么您需要以某种方式确保这些变量上有适当的互斥锁(互斥锁的范围是您面临的问题之一),并且线程都使用互斥锁,并释放互斥体。这更棘手。您甚至可能需要提供控制对变量的访问的函数。
标准变量errno可以是可修改的左值:
extern int *_errno_func(void);
#define errno (*(_errno_func)())
在线程应用程序(使用 -DREENTRANT 编译)中,会发生这种情况;在 MacOS X 上,这似乎是无论如何都会发生的事情(他们使用名称 __error 而不是 _errno_func;两者都在实现的命名空间中)。
您可能想要或最终不得不为您的变量做类似的事情。您说它们是静态的这一事实使情况有所改善。您只有一个文件要处理(除非您不小心将指向这些变量的指针传回 - 或 on - )。
【讨论】:
您需要的是TLS(Thread Local Storage),也称为thread-specific data或thread-private data。这种机制可以保证每个线程访问自己单独的数据副本,而不用担心与其他线程同步访问。
使用 TLS 有两种方法:
隐式:使用关键字
Windows: __declspec(thread) int tls_var = 10;
带有 GCC 的 Linux: __thread int tls_var = 10
显式:使用特定的 TLS 相关 API
Windows:
有关详细信息,请参阅 MSDN。
带有 GCC 的 LInux:
【讨论】:
大多数编译器都有一些指定线程本地存储的方法。假设它可用,那就是你想要的。
【讨论】: