静态局部变量中的竞争条件 我现在正在阅读有效的C++。有一节是关于使用静态局部变量的,它说如果多个线程访问一个静态变量,在初始化该变量时可能会出现争用情况
至少这是我的解释。这是真的吗?例如,在C#中,类静态变量的初始化永远不会有竞争条件 例如,在静态变量初始化期间,此代码是否具有竞争条件静态局部变量中的竞争条件 我现在正在阅读有效的C++。有一节是关于使用静态局部变量的,它说如果多个线程访问一个静态变量,在初始化该变量时可能会出现争用情况,c++,multithreading,initialization,singleton,race-condition,C++,Multithreading,Initialization,Singleton,Race Condition,至少这是我的解释。这是真的吗?例如,在C#中,类静态变量的初始化永远不会有竞争条件 例如,在静态变量初始化期间,此代码是否具有竞争条件 FileSystem& tfs() { static FileSystem fs; return fs; } 下面是这本书中的例外 以下是应用于tfs和tempDir的技术: class FileSystem { ... }; // as before FileSystem& tfs() // this replaces th
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++ 03标准没有提到线程,所以当C++实现添加它们时,他们就语言构造的线程安全做了他们想做的任何事情。一个常见的选择是不确保静态局部变量的线程安全初始化 在C++11中,局部静态变量保证在程序的控制流第一次通过其声明时被精确初始化一次,即使这在多个线程上同时发生
6.7/4
:
在与允许实现在命名空间范围(3.6.2)中静态初始化具有静态或线程存储持续时间的变量相同的条件下,允许实现执行具有静态或线程存储持续时间的其他块范围变量的早期初始化。否则,在控件第一次通过其声明时初始化该变量;此类变量在初始化完成时被视为已初始化。如果初始化通过抛出异常退出,则初始化未完成,因此下次控件进入声明时将再次尝试初始化。如果控件在初始化变量时并发输入声明,则并发执行应等待初始化完成
即便如此,这也只能确保初始化是安全的。如果计划同时使用从多个线程返回的文件系统
,文件系统
本身必须提供线程安全操作