4

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

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

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

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

或者它是实现定义的。

4

2 回答 2

4

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

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

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

于 2013-05-02T21:40:42.127 回答
3

在 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;
    ...
}

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

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

于 2013-05-02T21:34:40.663 回答