C++:多线程程序中的静态变量

30 c++ static multithreading

在多线程程序中使用静态变量(特别是在函数内)有什么问题?

谢谢.

Jam*_*lis 28

初始化不是线程安全的.两个线程可以进入该函数,并且两个线程都可以初始化函数范围的静态变量.这不好.没有人知道结果会是什么.

在C++ 0x中,函数范围静态变量的初始化将是线程安全的; 调用该函数的第一个线程将初始化该变量,并且调用该函数的任何其他线程将需要阻塞,直到该初始化完成.

我认为目前没有任何编译器+标准库对完全实现C++ 0x并发内存模型以及线程支持和原子库.


asv*_*kau 21

要随机选择一个说明性示例,请使用asctimeC库中的界面.原型看起来像这样:

 char *
 asctime(const struct tm *timeptr);
Run Code Online (Sandbox Code Playgroud)

这隐式地必须有一些全局缓冲区来存储char*返回的字符.实现这一目标的最常见和最简单的方法是:

 char *
 asctime(const struct tm *timeptr)
 {
    static char buf[MAX_SIZE];

    /* TODO: convert timeptr into string */

    return buf;
 }
Run Code Online (Sandbox Code Playgroud)

这在多线程环境中完全被破坏,因为buf每次调用都会处于相同的地址asctime().如果两个线程同时调用asctime(),则存在覆盖彼此结果的风险.合同中隐含的asctime()是字符串的字符将一直存在,直到下一次调用asctime(),并发调用会打破这一点.

在这个特定的例子中,有一些语言扩展通过线程局部存储(__thread,__declspec(thread))来解决这个特定问题.我相信这个想法使它成为C++ 0x作为thread_local关键字.

即便如此,我认为以这种方式使用它是一个糟糕的设计决策,原因类似于使用全局变量的原因.除此之外,它可以被认为是调用者维护和提供这种状态而不是被调用者的更清晰的接口.然而,这些是主观论点.