C++ 并发std::call\u once调用

C++ 并发std::call\u once调用,c++,c++11,C++,C++11,有人能解释一下为什么这个程序中的两个线程(使用Visual Studio 2012/2013附带的编译器编译时)都会被阻塞,直到执行了一次std::call\u调用为止?另一个VisualStudio bug(假设它在使用GCC编译时的行为与预期一致)?有人能想出一个解决办法吗?想象一下,为了缩小问题范围,我经历了多少痛苦,请你发发发慈悲吧 #include <chrono> #include <iostream> #include <mutex> #incl

有人能解释一下为什么这个程序中的两个线程(使用Visual Studio 2012/2013附带的编译器编译时)都会被阻塞,直到执行了一次
std::call\u
调用为止?另一个VisualStudio bug(假设它在使用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;
}
#包括
#包括
#包括
#包括
名称空间
{
标准::一旦标志没有做什么;
什么都不做
{ }
无效睡眠时间更短,什么也不做一次()
{
std::this_thread::sleep_for(std::chrono::seconds(3));

std::cout它更倾向于一种错误行为。
“对once\u标志对象调用once的有效调用的完成与对同一once\u标志对象调用once\u的所有后续调用同步。”(N3242,30.4.4.2-clause-3)

我收到了微软STL维护人员的回复,称该漏洞已在Visual Studio 2015中修复。

如果它是指向您的answer@UmNyobe对不起,那是一封电子邮件。不管怎么说,那是很久以前的事了。我显然不应该在我以前的问题中修改语法/格式,因为出于某种原因,这会引发很多新问题评论!在VS2015发行说明中提到,在DevDiv#1092852下: