【发布时间】:2014-05-25 13:55:21
【问题描述】:
我目前正在阅读《Effective C++》。有一节是关于使用静态局部变量的,它说如果多个线程访问一个静态变量,那么在该变量的初始化过程中可能会出现竞争条件。
至少这是我的解释。这是真的?例如,在 C# 中,类静态变量的初始化永远不会有竞争条件。
例如,这段代码在静态变量初始化期间可以有竞态条件吗?
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
以下是书中的例外。
这是应用于 tfs 和 tempDir 的技术:
class FileSystem { ... }; // as before FileSystem& tfs() // this replaces the tfs object; it could static in the FileSystem class { static FileSystem fs; // define and initialize a local static object return fs; // return a reference to it }.
class Directory { ... }; // as before Directory::Directory( params ) // as before, except references to tfs are now to tfs() { ... std::size_t disks = tfs().numDisks(); ... } Directory& tempDir() // this replaces the tempDir object; it could be static in the Directory class { static Directory td; // define/initialize local static object return td; // return reference to it }这个修改过的系统程序的客户和他们以前一样, 除了他们现在引用
tfs()和tempDir()而不是tfs和tempDir。也就是说,它们使用返回对象引用的函数 而不是使用对象本身。此方案规定的引用返回函数总是 简单:在第 1 行定义并初始化一个本地静态对象,返回 它在第 2 行。这种简单性使它们成为 内联,尤其是当它们被频繁调用时(参见条款 30)。在 另一方面,这些函数包含静态对象的事实 使它们在多线程系统中出现问题。 再一次,任何种类 非常量静态对象(本地或非本地)的等待很麻烦 在存在多个线程的情况下发生。一种处理方式 这样的麻烦是手动调用所有的引用返回 在程序的单线程启动部分运行。 这消除了与初始化相关的竞争条件。
【问题讨论】:
标签: c++ multithreading initialization singleton race-condition