And*_*rew 19 c++ multithreading initialization c++11 c++03
假设有一个函数(可能是成员函数)
SomeType foo()
{
static SomeType var = generateVar();
return var;
}
Run Code Online (Sandbox Code Playgroud)
var如果foo将同时从多个线程"第一次"调用,将如何初始化?
generateVar()在任何情况下只调用一次(如果使用的话)?foo在任何情况下多次调用时都会返回相同的值?And*_*owl 25
关于C++ 03:
由C++ 03标准定义的抽象机器不包含线程是什么的正式定义,以及如果同时访问对象,程序的结果应该是什么.
没有同步原语的概念,在不同线程中执行的操作的排序,数据竞争等等.因此,根据定义,每个多线程C++ 03程序都包含未定义的行为.
当然,在实践中,实现确实提供了记录的行为,但标准中没有任何内容指定此行为应该是什么.因此,我会说这取决于你的编译器.
其余的答案将集中在C++ 11上,它确实定义了并发操作的语义.
关于C++ 11:
是否保证
generateVar()在任何情况下只调用一次(如果使用的话)?
不,不是在任何情况下.
初始化var保证是线程安全的,所以generateVar()不会同时输入,但是如果抛出异常generateVar(),或者由复制构造函数或移动构造函数抛出SomeType(SomeType当然,如果是UDT),那么初始化将是下次执行流程进入声明时重新尝试 - 这意味着generateVar()将再次调用.
根据C++ 11标准的6.7/4段,初始化具有静态存储持续时间的块范围变量:
[...]如果初始化通过抛出异常退出,则初始化未完成,因此下次控制进入声明时将再次尝试.如果控制在初始化变量时同时进入声明,则并发执行应等待初始化完成.如果控件在初始化变量时以递归方式重新输入声明,则行为未定义.[...]
关于你的下一个问题:
是否保证foo在任何场景中多次调用时都会返回相同的值?
如果它将设法返回一个值(见上文),那么是.
原始类型或非原始类型的行为是否存在差异?
不,没有,除了没有复制构造函数或原始类型的移动构造函数这样的东西,因此复制初始化也不会导致抛出异常(除非当然generateVar()抛出).
| 归档时间: |
|
| 查看次数: |
1578 次 |
| 最近记录: |