gpt4 book ai didi

c++ - 静态局部变量中的竞争条件

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:14:18 25 4
gpt4 key购买 nike

我目前正在阅读 Effective C++。有一个关于使用静态局部变量的部分,它说如果多个线程访问一个静态变量,则在该变量的初始化期间可能会出现竞争条件。

至少这是我的解释。这是真的?例如,在 C# 中,类静态变量的初始化永远不会出现竞争条件。

例如,此代码在静态变量初始化期间是否存在竞争条件?

FileSystem& tfs()
{
static FileSystem fs;
return fs;
}

以下是书中的异常(exception)情况。

Here's the technique applied to both tfs and 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
}

Clients of this modified system program exactly as they used to, except they now refer to tfs() and tempDir() instead of tfs and tempDir. That is, they use functions returning references to objects instead of using the objects themselves.

The reference-returning functions dictated by this scheme are always simple: define and initialize a local static object on line 1, return it on line 2. This simplicity makes them excellent candidates for inlining, especially if they're called frequently (see Item 30). On the other hand, the fact that these functions contain static objects makes them problematic in multithreaded systems. Then again, any kind of non-const static object — local or non-local — is trouble waiting to happen in the presence of multiple threads. One way to deal with such trouble is to manually invoke all the reference-returning functions during the single-threaded startup portion of the program. This eliminates initialization-related race conditions.

最佳答案

此部分已过时。 C++03 标准没有提到线程,因此当 C++ 实现添加它们时,它们会在语言构造的线程安全方面做任何他们想做的事情。一个常见的选择是不确保静态局部变量的线程安全初始化。

在 C++11 中,局部静态变量保证只被初始化一次,即程序的控制流第一次通过它们的声明时,即使这在多个线程上同时发生也是如此 6.7/4:

An implementation is permitted to perform early initialization of other block-scope variables with static or thread storage duration under the same conditions that an implementation is permitted to statically initialize a variable with static or thread storage duration in namespace scope (3.6.2). Otherwise such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

即便如此,这也只能确保初始化是安全的。如果您计划同时使用从多个线程返回的 FileSystemFileSystem 本身必须提供线程安全操作。

关于c++ - 静态局部变量中的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23856003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com