简体   繁体   English

是否保证主要的全局初始化程序能够运行单线程?

[英]Are pre-main global initializers guaranteed to run single-threaded?

For example, the node::node() constructor in the following snippet accesses the globals node::count and ::tail without any multithread guards. 例如,以下代码段中的node::node()构造函数访问globals node::count::tail而不使用任何多线程保护。 Does the C++ standard guarantee that the output would always be a permutation of 0 1 2 (regardless of the order)? C ++标准是否保证输出始终是0 1 2的排列(无论顺序如何)?

#include <stdio.h>

struct node *tail;

struct node
{
    static int count;

    int index;
    node *prev;

    node()
    {   index = count++; prev = tail; tail = this; }
};

int node::count;

node one, two[2];

int main(int argc, char *argv[])
{
    for(node *p = tail; p; p = p->prev)
        printf("%d\n", p->index);

    return 0;
}

I am looking for an answer based on the (applicable) standard, not for implementation or compiler specific behaviors. 我正在寻找基于(适用)标准的答案,而不是针对实现或编译器特定行为。 There are a number of related questions on SO but it's not entirely clear how they directly apply to this particular and rather basic case ( Is C++ static member variable initialization thread-safe? , Is local static variable initialization thread-safe in C++11? etc). 关于SO有很多相关的问题但是它们并不完全清楚它们是如何直接应用于这个特殊且相当基本的情况( C ++静态成员变量初始化线程安全吗?C ++ 11中的局部静态变量初始化线程 安全吗? 等)。

Initialization of global variables is guaranteed single-threaded as long as the program doesn't itself start a thread (eg in a constructor of some global variable); 只要程序本身不启动线程(例如在某个全局变量的构造函数中),全局变量的初始化就可以保证是单线程的。 once that happens, the implementation is then allowed to parallellize remaining initializations, to some extent. 一旦发生这种情况,就可以在一定程度上实现剩余的初始化。

[basic.start.init]/2 ...Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit. [basic.start.init] / 2 ...在单个翻译单元中定义的有序初始化的变量应按其在翻译单元中的定义顺序进行初始化。 If a program starts a thread (30.3), the subsequent initialization of a variable is unsequenced with respect to the initialization of a variable defined in a different translation unit. 如果程序启动一个线程(30.3),则对于在不同转换单元中定义的变量的初始化,后续的变量初始化是未排序的。 Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization of a variable defined in a different translation unit. 否则,对于在不同转换单元中定义的变量的初始化,变量的初始化是不确定地排序的。 If a program starts a thread, the subsequent unordered initialization of a variable is unsequenced with respect to every other dynamic initialization. 如果程序启动一个线程,则对于每个其他动态初始化,后续无序的变量初始化都是无序的。 Otherwise, the unordered initialization of a variable is indeterminately sequenced with respect to every other dynamic initialization. 否则,对于每个其他动态初始化,变量的无序初始化是不确定地排序的。 [ Note: This definition permits initialization of a sequence of ordered variables concurrently with another sequence. [ 注意:此定义允许与另一个序列同时初始化一系列有序变量。 —end note ] - 尾注 ]

"Indeterminately sequenced" is the part that guarantees single-threaded execution. “不确定顺序”是保证单线程执行的部分。 By definition, the notion of sequenced {before, after, indeterminately} is only meaningful within a single thread: 根据定义, 排序{before,after,indeterminately}的概念仅在单个线程中有意义:

[intro.execution]/13 Sequenced before is a ... relation between evaluations executed by a single thread... [intro.execution] / 13 之前的顺序是......由单个线程执行的评估之间的关系......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM