C++ 做任何C++;11线程安全保证适用于使用C+编译/链接的第三方线程库+;11?

C++ 做任何C++;11线程安全保证适用于使用C+编译/链接的第三方线程库+;11?,c++,thread-safety,c++11,language-lawyer,C++,Thread Safety,C++11,Language Lawyer,C++11提供了如下功能,并引用了这个问题,例如: Logger& g_logger() { static Logger lg; return lg; } 因此,表面上(?)这是正确的,无论使用C++11编译器编译的模块是否包含线程头,或者是否在其主体中生成了任何线程。即使它与另一个使用C++11线程并调用该函数的模块相链接,您也可以得到保证 但是,如果调用此代码的“其他模块”不是使用C++11线程,而是类似于Qt的QThread,该怎么办呢。那么,静态的原子初始化是否

C++11提供了如下功能,并引用了这个问题,例如:

Logger& g_logger() {
    static Logger lg;
    return lg;
}
因此,表面上(?)这是正确的,无论使用C++11编译器编译的模块是否包含线程头,或者是否在其主体中生成了任何线程。即使它与另一个使用C++11线程并调用该函数的模块相链接,您也可以得到保证

但是,如果调用此代码的“其他模块”不是使用C++11线程,而是类似于Qt的
QThread
,该怎么办呢。那么,静态的原子初始化是否超出了C++11提供这种保证的能力范围?或者,仅仅是一个模块已经用C++11编译,然后与其他C++11代码链接,这是否意味着不管怎样,您都会得到保证

有人知道这样的问题涉及到哪里吗

有人知道这样的问题涉及到哪里吗

当然。C++标准。它描述了C++代码的行为。如果库是C++代码,则需要遵循此行为。因此,是的,您得到了与您自己的代码相同的保证


编译器/运行时/操作系统/其他一切如何实现这一点,这不是您的问题。C++标准保证了它被处理。

< P>你的例子依赖于内存模型,而不是线程如何实现。执行此代码的人将执行相同的指令。如果两个或多个内核执行此代码,它们将遵循内存模型

基本实现相当于:

std::mutex mtx;
Logger * lg = 0;
Logger& g_logger() {
    std::unique_lock<std::mutex> lck(mtx);
    if (lg == 0)
        lg = new Logger;
    return *lg;
}
std::mutex-mtx;
记录器*lg=0;
记录器&g_记录器(){
标准:唯一锁定lck(mtx);
如果(lg==0)
lg=新记录器;
返回*lg;
}

此代码可以优化为使用双重检查锁定模式(DCLP),在特定处理器体系结构(例如x86)上,DCLP可能会快得多。此外,由于编译器生成此代码,它将知道不要进行破坏原始DCLP的疯狂优化。

静态初始化是一种语言属性。我看不出特定库会如何影响这一点。@pmr这对我来说似乎有点棘手,因为——例如——上面静态的内存是在程序开始时分配的,但构造函数在第一次调用包含静态的函数时运行。要实现这一点,似乎需要对底层线程模型有全面的了解,因此我怀疑,如果混合使用QThread/C++11thread,它是否能够正确运行……尽管有一点可能会出现新的二进制要求。@HostileFork:只要(C++和qt)使用相同的操作系统工具来执行线程,我不知道怎么会出问题。我也不明白为什么两者都不应该使用操作系统线程功能。不过底层线程模型是已知的。QThreads只是一个包装器。它们在C++库中实现,因此它们的行为就像C++一样,线程应该表现出来。C++标准描述了“执行线程”。它并没有说它们必须创建为
std::thread
对象。根据C++11点,pthread、Boost.Thread和QThread都是有效的执行线程。然而,不管这是否是我的问题,我想知道我是否使用GCC和Qt,他们是否真的“成功”了。从技术角度来看,如果一个C++03
static.a
库链接到一个C++11
icallthestatic
可执行文件,那么链接器不太可能做到这一点。但这指向了一个更广泛的问题:“您可能无法将C++03代码与C++11链接,并获得系统的C++11保证”……C++03代码的行为只能保证与C++03类似。所以,如果你链接到一个C++03库,你不能指望它实现只有C++11提供的保证,谢谢…看起来大家一致认为这应该是安全的。仅供参考:我调查的原因是为了解决这个问题。。。