函数使用本地静态变量线程安全/可重入

时间:2013-05-02 21:20:40

标签: c linux thread-safety

我有一个函数可以为调用它的不同线程生成一个唯一的随机数(基本上是递增的)。

这个线程是安全的还是可重入的?假设我使用静态变量来表示这个数字。

我在本论坛中看到静态变量不能用于重入/线程安全。

它是否适用于本地/全局静态。

或者是实施定义。

2 个答案:

答案 0 :(得分:3)

更改线程之间共享的“普通”对象绝不是线程安全的,除非您特别注意它。 (并且任何静态声明的变量都属于该类别)。有两种标准的处理方法

  • 使用互斥锁或其他锁结构来保护“关键部分”内的共享对象
  • 使用原子操作来访问对象,新的C标准,C11具有此接口

重写是否执行(即使没有线程)可以修改部分状态,例如递归,信号处理程序或跳转gotolongjmp。把它想象成与“你自己”共享一个变量。如果从程序的不同位置修改它们,静态分配的变量在这里会产生同样的问题。

答案 1 :(得分:1)

在C中,本地static变量以线程安全的方式初始化,因为它们总是在程序启动时初始化,然后才能创建任何线程。由于这个原因,不允许使用非常量值初始化本地static变量。

void some_function(int arg)
{
    // This initialization is thread-safe and reentrant, since it happens at
    // program startup
    static int my_static = 42;

    // ERROR: Initializer is not constant
    static int another_static = arg;
    ...
}

当然,整个函数是否是线程安全的或可重入的完全取决于你使用静态变量的方式。由于它们实际上与全局变量相同,因此在读取或写入它们(或其他同步结构)时需要确保使用正确的互斥锁以确保线程安全。

为了确保函数是可重入的,您需要仔细检查函数何时以及如何调用自身(可能通过另一个函数间接调用),并确保所有全局状态都表现一致。