我试图编写一个测试(不检查汇编代码),看看某个编译器是否符合c ++ 11标准关于静态本地对象初始化的线程安全要求。 / p>
到目前为止,我只能提出非确定性方法(在一个线程上休眠足够长的时间以使另一个线程运行到某个执行点的可能性(但不一定是问题!))
有没有办法确定性地做到这一点?
答案 0 :(得分:0)
E.g。一个 sync voodoo (见评论),如下所示:
#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)在ctor中等待,并且期望的行为是,第二个(不一定是t1)线程在之前等待挂起的静态变量init(在第一个线程中)完成。
所以在锁定尝试之前只有一个对#34;&#34; /&#34;在锁定尝试之后#34;如果编译器正常工作,则打印消息。
g ++(Debian 4.8.2-16)表现良好。
如果t1,t2本身管理主线程的控制流, voodoo 可以放到顶部;我跳过了,只是设置了一个计时器。