静态局部变量中的争用条件
Race conditions in static local variables
我目前正在阅读有效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++03标准没有提到线程,所以当C++实现添加线程时,他们在语言结构的线程安全方面做了任何他们想做的事情。一个常见的选择是不确保静态局部变量的线程安全初始化。
在 C++11 中,局部静态变量保证只初始化一次,即程序的控制流第一次通过其声明时,即使这在多个线程上并发发生6.7/4
:
允许实现在允许在命名空间作用域 (3.6.2( 中静态初始化具有静态或线程存储持续时间的变量的相同条件下,使用静态或线程存储持续时间执行其他块范围变量的早期初始化。否则,此类变量在控件第一次通过其声明时初始化;此类变量在其初始化完成后被视为已初始化。如果初始化通过引发异常退出,则初始化未完成,因此下次控件进入声明时将再次尝试初始化。如果在初始化变量时控件并发进入声明,则并发执行应等待初始化完成。
即便如此,这也只能确保初始化是安全的。如果计划同时使用从多个线程返回的FileSystem
,FileSystem
本身必须提供线程安全操作。
- 并行块(线程清理器)之外的 OpenMP 中的争用条件;误报?
- 如何在C++中创建争用条件
- C++上的手动重置事件(来自 C#)实现:如何避免争用条件
- 作为随机数生成器的争用条件
- 智能指针析构函数争用条件
- 尽管互斥锁,线程中的争用条件
- 在C++中递增和递减全局变量时的争用条件
- 为什么此代码不创建争用条件?
- __has_include() 和后续 #include 之间是否存在争用条件
- 什么保证两个不相关的线程中的不同不相关对象没有(不可避免的)争用条件?
- 此工厂方法是否会导致争用条件?
- 争用条件 2 个线程交替
- 标准::condition_variable 中可能存在的争用条件
- 启动子进程时的争用条件导致从管道读取挂起
- 当只有一个线程写入 c++ 中的布尔变量时,是否存在争用条件
- 避免在增加计数器时出现争用条件
- 是否有 std 或提升容器可以避免其插入和查找方法之间的争用条件
- 增强进程间争用条件预防
- 如何在 VxWorks 中的条件变量中避免争用条件
- 静态局部变量中的争用条件