测试静态局部对象的初始化是否线程安全

Testing if the initialization of static local objects is thread-safe

本文关键字:是否 线程 安全 初始化 静态局 对象 测试      更新时间:2023-10-16

我想写一个测试(不检查汇编代码),看看某个编译器是否符合c++11标准中关于静态局部对象初始化的线程安全要求。

到目前为止,我只能提出非确定性方法(在一个线程上睡眠足够长的时间,以使另一个线程有可能(但不确定,问题!)运行到某个执行点)。

是否有一种方法可以确定地做到这一点?

一个同步巫术(见注释)像这样:

#include <thread>
#include <mutex>
#include <chrono>
#include <iostream>
std::mutex g_mutex;
const std::chrono::seconds g_dura(1);
void log(const char* msg) {
    std::clog << std::this_thread::get_id() 
              << " "  << msg 
              << std::endl;
}
struct Asset {
    Asset () {
        log("before lock attempt");
        g_mutex.lock();
        log("after lock attempt");
        /*EDIT*/g_mutex.unlock();
    }
};
void test() {
    log("entering test()");
    static Asset asset; 
    log("leaving test()");
}
int main() {
    g_mutex.lock();
    std::thread t1(test), t2(test);
    std::this_thread::sleep_for(g_dura);
    // cleanup
    g_mutex.unlock();
    t1.join();
    t2.join();
}

这使得必须执行init的第一个线程(不一定是t1)在actor中等待,并且期望的行为是,第二个线程(不一定是t1)在挂起的静态变量init(在第一个线程中)完成之前等待

因此,如果编译器工作正常,只会打印出一对对"before lock attempt"/"after lock attempt"消息。

g++ (Debian 4.8.2-16)表现良好。

如果t1、t2本身管理主线程的控制流,则voodoo可以放在首位;我跳过了它,只是设置了一个计时器。