我在C库中有全局静态变量,它在多线程运行中生成异常。我需要以某种方式使它们安全(即,每个线程应该与这些变量的不同实例相关)。任何推荐的方法?
答案 0 :(得分:10)
没有标准方法适用于所有C实现,但存在特定于实现的解决方案。例如,使用Microsoft的编译器(请参阅the docs),
__declspec( thread ) int tls_i = 1;
使tls_i
存在于线程本地存储中(每个线程都有自己独立的此变量实例)。使用gcc时,语法为
__thread int tls_i;
您可能还想查看主题的wikipedia entry。
答案 1 :(得分:4)
第一个问题:
如果你需要前者,其他答案就“线程本地存储”提出了建议。
如果你需要后者,那么你需要以某种方式确保这些变量上有一个合适的互斥锁(互斥锁的范围是你面临的问题之一),并且线程都使用互斥锁,并释放互斥体。这比较棘手。甚至可能需要提供控制对变量的访问的函数。
标准变量errno
可以是可修改的左值:
extern int *_errno_func(void);
#define errno (*(_errno_func)())
在线程应用程序(使用-DREENTRANT编译)中,会发生这种情况;在MacOS X上,无论如何它似乎都会发生(它们使用名称__error
而不是_errno_func
;两者都在实现的命名空间中。
您可能希望或最终必须为您的变量做类似的事情。你说它们是静态的这一事实可以改善一些事情。你只有一个文件要处理(除非你不小心传回 - 或指向那些变量的指针)。
答案 2 :(得分:3)
您需要的是 TLS(线程本地存储),也称为线程特定数据或线程专用数据。这种机制可以保证每个线程访问自己独立的数据副本,而不必担心与其他线程同步访问。
使用TLS有两种方法:
隐含:使用关键字
Windows: __declspec(thread)int tls_var = 10;
使用GCC的Linux: __thread int tls_var = 10
明确:使用特定的TLS相关API
<强>窗:强>
有关详细信息,请参阅MSDN。
LInux与GCC:
答案 3 :(得分:1)
大多数编译器都有一些指定线程本地存储的方法。假设它可用,那就是你想要的。