You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中全局变量的初始化是否会在多线程中进行?

全局变量多线程初始化的疑问与测试

在Bjarne Stroustrup所著《C++ Programming Language》第四版的15.4.2节中,有如下内容:

考虑以下代码:

int x = 3;
int y = sqrt(++x);

x和y的值可能是什么?直观答案是“3和2!”。原因是:用常量表达式初始化的静态分配对象在链接时完成初始化,所以x变为3。但y的初始化器不是常量表达式(sqrt()不是constexpr),因此y要到运行时才初始化。不过单个翻译单元中静态分配对象的初始化顺序是明确的:按定义顺序初始化(§15.4.1),所以y变为2。
上述推论的漏洞在于:如果使用多线程(§5.3.1、§42.2),每个线程都会执行运行时初始化,且没有隐式提供互斥机制来防止数据竞争。那么一个线程中的sqrt(++x)可能在另一个线程完成x自增之前或之后执行,因此y的值可能是sqrt(4)或sqrt(5)。

疑问

  • 实际开发中,多线程初始化全局变量的场景具体是怎样的?
  • 如果在main()函数前声明全局std::thread变量并启动线程,会不会影响其他全局变量的初始化?

测试代码

#include <iostream>
#include <thread>

using namespace std;

extern int x;
extern double y;

struct Foo {
    Foo() { cout << "Foo::Foo()" << '\n'; }
};

void threadFunc() {
    cout << "x = " << x << '\n';
    cout << "y = " << y << '\n';
}

thread t{threadFunc};

int x = 3;
double y = sqrt(double(++x));
Foo z;

int main() {

    cout << "x = " << x << '\n';
    cout << "y = " << y << '\n';
    t.join();

    return 0;
}

测试结果

使用MSVC 17.5.2版本多次运行该程序,结果始终一致:y的值为2,Foo的构造函数仅被调用一次。

内容的提问来源于stack exchange,提问作者bobeff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:32:34