我在C库中具有全局静态变量,该变量在多线程运行中生成异常。我需要以某种方式使它们安全(即,每个线程都应与这些变量的不同实例有关)。有建议的方法吗?

有帮助吗?

解决方案

在所有C实施中都没有标准方法,但是存在特定于实施的解决方案。例如,使用Microsoft的编译器(请参阅 文档),

__declspec( thread ) int tls_i = 1;

制作 tls_i 实时在线程 - 本地存储中(每个线程都有其自己的独立实例)。和 海湾合作委员会, ,语法是

__thread int tls_i;

您可能还想检查 Wikipedia条目 就此主题而言。

其他提示

第一个问题:

  • 线程需要自己的变量副本吗?
  • 还是他们需要协调对单个共享副本的访问?

如果您需要前者,其他答案就提出了有关“线程本地存储”的建议。

如果需要后者,则需要以某种方式确保这些变量上有适当的静音(静音的范围是您所面临的问题之一),并且线程都使用了sutex,并释放了mutex。这很棘手。甚至可能是您需要提供控制对变量的访问的功能。

标准变量 errno 可以是可修改的lvalue:

extern int *_errno_func(void);
#define errno (*(_errno_func)())

在螺纹应用程序(用-drentrant编译)中,这就是发生的事情。在MacOS X上,似乎无论如何都会发生(他们使用名称 __error 代替 _errno_func;两者都在实现的命名空间中)。

您可能需要或最终必须为变量做类似的事情。您说它们是静态的事实可以有所改善。您只有一个文件可以处理(除非您不小心可以向这些变量传递给或启用指针)。

您需要的是 TLS(线程本地存储), ,也称为 特定于线程的数据 或者 线程私人数据. 。该机制可以保证每个线程访问其自己的单独的数据副本,而不必担心将访问与其他线程同步。


有两种使用TLS的方法:

  1. 隐式:使用关键字

    视窗: __declSpec(thread)int tls_var = 10;

    Linux与GCC: __ thread int tls_var = 10

  2. 显式:使用特定TLS相关的API

    视窗:

      tlsalloc(): 为TLS数据分配内存
      tlsfree(): 免费记忆TLS数据
      tlssetValue(): 设置TLS的值
      tlsgetValue(): 获取TLS的价值

    请参阅MSDN以获取详细信息。

    Linux与GCC:

      pthread_key_create(): :创建TLS数据
      pthread_key_delete(): :destory TLS数据
      pthread_getspecific(): :获取TLS的价值
      pthread_setspefific():设置TLS的值
    转向manpage获取特定和详细信息。

大多数编译器都有某种方式指定线程本地存储。假设它可用,这就是您想要的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top