C++ 程序意外阻塞/抛出

标签 c++ multithreading c++11

我正在学习 C++ 中的互斥锁,但以下代码(摘自 N. Josuttis 的“C++ 标准库”)有问题。

我不明白为什么它会阻塞/抛出除非我在主线程中添加this_thread::sleep_for(然后它不会阻塞并且所有三个调用都是执行)。

编译器是从命令行使用的 cl.exe。

#include <future>
#include <mutex>
#include <iostream>
#include <string>
#include <thread>
#include <chrono>

std::mutex printMutex;

void print(const std::string& s)
{
    std::lock_guard<std::mutex> lg(printMutex);

    for (char c : s)
    {
        std::cout.put(c);
    }
    std::cout << std::endl;
}

int main()
{
    auto f1 = std::async(std::launch::async, print, "Hello from thread 1");
    auto f2 = std::async(std::launch::async, print, "Hello from thread 2");

    // std::this_thread::sleep_for(std::chrono::seconds(1));

    print(std::string("Hello from main"));       
}

最佳答案

我认为您看到的是 async(结合 future)的 MSVC 实现的一致性问题。我相信是not conformant .我能够使用 VS2013 重现它,但无法使用 gcc 重现该问题。

崩溃是因为主线程在其他两个线程完成之前退出(并开始清理)。

因此,两个 futures 上的简单延迟(sleep_for)或 .get().wait() 应该修复它你。所以修改后的 main 可能看起来像;

int main()
{
    auto f1 = std::async(std::launch::async, print, "Hello from thread 1");
    auto f2 = std::async(std::launch::async, print, "Hello from thread 2");

    print(std::string("Hello from main"));       

    f1.get();
    f2.get();
}

支持显式等待或克服定时“ sleep ”。

一致性说明

有来自 Herb Sutter 的提议更改等待或阻止从 async 返回的 future 的共享状态。这可能是 MSVC 行为的原因,它可以被视为已实现该提案。我不确定该提案的最终结果是什么,或者它与 C++14 的集成(或其中的一部分)是什么。至少 w.r.t.阻止从 async 返回的 future 看起来 MSVC 行为没有进入规范。

有趣的是,§30.6.8/5 中的措辞发生了变化;

来自 C++11

a call to a waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined

到 C++14

a call to a waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined, or else time out

我不确定如何指定“超时”,我想它是实现定义的。

关于C++ 程序意外阻塞/抛出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26278797/

相关文章:

c++ - 析构函数 vs 成员函数再次竞赛

c++11 - 在部分副本中使用 for_each

c++ - 程序使用 clang++ 编译,但 g++ 耗尽 RAM 并失败

c++ - intptr_t 是 uintptr_t 的签名拷贝吗(反之亦然)?

c++ - 无法在 Windows 上将 SDL 与 MinGW 一起使用

c++ - 直接列表初始化的自动规则

android - 动画师只能在 Sherlock 操作栏上的 Looper 线程上运行

c++ - 从文件中添加不正确

c++ - STL 双端队列 : keep minimum size

multithreading - Node.js 异步逻辑行为