C++ 在启动多线程代码之前初始化

C++ 在启动多线程代码之前初始化,c++,x86,memory-barriers,C++,X86,Memory Barriers,正如我们所看到的,它破坏了我们的计划 我知道,编译器必须非常聪明才能做到这一点。特别是,编译器必须知道初始化X意味着什么。因此,它必须非常智能。 但是,我们能假设它不是吗 你怎么看?如果编译器没有看到startMultitreadingServer函数的代码,那么语言规范禁止在函数调用过程中移动任何代码 如果编译器看到startMultitreadingServer函数的代码,那么它应该在函数内部找到一个内存障碍或任何导致此效果的操作。任何线程启动功能内部都应该有一个内存屏障;这应在其合同/说明

正如我们所看到的,它破坏了我们的计划

我知道,编译器必须非常聪明才能做到这一点。特别是,编译器必须知道初始化X意味着什么。因此,它必须非常智能。 但是,我们能假设它不是吗

你怎么看?

如果编译器没有看到startMultitreadingServer函数的代码,那么语言规范禁止在函数调用过程中移动任何代码

如果编译器看到startMultitreadingServer函数的代码,那么它应该在函数内部找到一个内存障碍或任何导致此效果的操作。任何线程启动功能内部都应该有一个内存屏障;这应在其合同/说明中说明。同样,编译器至少不能移动,向前移动任何代码绕过这个障碍


因此,在任何情况下,编译器都不能在线程创建函数调用之前、调用之后移动代码。

在什么之间不需要任何内存障碍?。而编译器当然不能移动调用initSharedResourceX;对于handlerI,我会说线程创建是一个内存障碍。@RbMm,编译器当然不能移动调用initSharedResourceX;因为…如果您正在创建一个线程并进行系统调用来执行此操作,除非您的应用程序处于特权上下文中,如环0,当您执行上下文切换时,它会创建一个隐式内存障碍。编译器不会移动对initSharedResourceX的调用,因为要这样做,它需要证明它在“仿佛”规则下是安全的。这需要知道initShareResourceX做了什么,以便生成条件,如果编译器如何知道X已初始化?。intSharedResourceX不需要一个完整的屏障,但至少需要一个写释放作为最后一个操作。然而,线程创建通常是一个同步操作。检查你的线程创建库,看看是否是这样。好的,谢谢。我不知道创建线程是一个障碍,但它似乎是合理的。当我们假设没有导致障碍的操作时,我的怀疑是否合理?当我们假设没有导致障碍的操作时,我的怀疑是否合理如果没有屏障,语义线程创建函数可能会被破坏——我很难想象没有内部屏障的函数会以CPU缓存安全的方式初始化新线程的内存。但是,如果函数实际上没有通过障碍,那么在某些情况下,编译器可以在函数调用周围移动代码。
int main(){
    // X is a shared resource
    initSharedResourceX();
    startMultitreadingServer(); // handle requests concurrently with function handle() <- below. All handlers (run concurrently) access to X **read-only**.


}

int handle(){
    return X.get(); // get() is read-only
}
int main(){
    startMultitreadingServer(); 
}

int handle(){
    if(X is not initialized) {
        initSharedResourceX();
    }
    return X.get(); 
}