gpt4 book ai didi

c++ - 多线程环境中的静态局部变量初始化

转载 作者:IT老高 更新时间:2023-10-28 21:56:40 29 4
gpt4 key购买 nike

假设有一个函数(可能是成员函数)

SomeType foo()
{
static SomeType var = generateVar();
return var;
}

如果 foo 将被多个线程同时“首次”调用,var 将如何初始化?

  1. 是否保证 generateVar() 在任何情况下都只会被调用一次(当然如果使用的话)?
  2. 是否保证 foo 在任何场景下多次调用都会返回相同的值?
  3. 原始类型和非原始类型的行为有区别吗?

最佳答案

关于 C++03:

C++03 标准定义的抽象机不包含关于什么是线程的正式定义,以及如果同时访问一个对象,程序的结果应该是什么。

没有同步原语、在不同线程中执行的操作排序、数据竞争等的概念。因此,根据定义,每个多线程 C++03 程序都包含未定义的行为。

当然,在实践中,实现确实提供了记录在案的行为,但标准中没有任何内容指定这种行为应该是什么。因此,我会说这取决于您的编译器。

答案的其余部分将集中在 C++11,它确实定义了并发操作的语义。

关于 C++11:

Is it guaranteed that generateVar() will be called only once in any scenario (if used of course)?

不,在任何情况下都不会。

var的初始化保证是线程安全的,所以generateVar()不会同时进入,但是如果抛出异常generateVar(),或者通过SomeType的copy构造函数或者move构造函数(如果SomeType当然是UDT),那么会重新初始化下次执行流程进入声明时 - 这意味着 generateVar() 将再次被调用。

根据 C++11 标准的第 6.7/4 段关于使用静态存储持续时间初始化 block 范围变量:

[...] 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. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined. [...]

关于你的下一个问题:

Is it guaranteed that foo will return the same value when called multiple times in any scenario?

如果它能够返回一个值(见上文),那么是的。

Is there a difference in behaviour for primitive or non-primitive types?

不,没有,除了原始类型没有复制构造函数或移动构造函数之类的东西,因此复制初始化也不会导致抛出异常的风险(当然除非 generateVar() 抛出)。

关于c++ - 多线程环境中的静态局部变量初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16734966/

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