请有人解释一下,为什么这个程序中的两个线程(在使用Visual 2012/2013附带的编译器进行编译时)被阻塞,直到执行两个std::call_once调用?另一个Visual错误(考虑到它在与GCC一起编译时的行为与预期相同)?谁能想出个解决办法吗?想象一下我为缩小问题而经历的所有痛苦,请宽恕我。
#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>
namespace
{
std::once_flag did_nothing;
void do_nothing()
{ }
void sleep_shorter_and_do_nothing_once()
{
std::this_thread::sleep_for(std::chrono::seconds(3));
std::cout << "1\n";
std::call_once(did_nothing, do_nothing);
std::cout << "2\n";
}
std::once_flag sleeped_longer;
void sleep_longer()
{
std::this_thread::sleep_for(std::chrono::seconds(10));
}
void sleep_longer_once()
{
std::cout << "3\n";
std::call_once(sleeped_longer, sleep_longer);
std::cout << "4\n";
}
}
int main()
{
std::thread t1(sleep_shorter_and_do_nothing_once);
std::thread t2(sleep_longer_once);
t1.join();
t2.join();
return 0;
}详细说明,在使用GCC编译时,它的行为与预期相同:
当使用Visual 2012/2013附带的编译器进行编译时,它的行为如下:
很明显,这是一种不当行为。或者不是?
更新:--我不能将它作为Visual错误提交,因为我的工作帐户由于某些原因“无权为这个连接提交反馈”,不管这意味着什么。我得到了微软STL维护者的回复,他说他希望在将来的某个时候会对这个问题进行调查。
发布于 2015-04-29 23:22:50
微软的STL维护人员给我的答复是,这个bug在Visual 2015中得到了修复。
发布于 2014-10-21 01:06:50
它宁愿是一种不当行为。
“在call_once对象上完成对once_flag的有效调用将与对上的call_once --同一个once_flag对象--的所有后续调用同步。”(N3242,30.4.4.2-第3条)。
https://stackoverflow.com/questions/26477070
复制相似问题