簡體   English   中英

C ++程序意外阻止/拋出

[英]C++ program unexpectedly blocks / throws

我正在學習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的MSVC實現(與future相結合)的一致性問題。 我認為這不符合要求 我能用VS2013重現它,但無法用gcc重現這個問題。

崩潰是因為主線程在其他兩個線程完成之前退出(並開始清理)。

因此,兩個期貨的簡單延遲( 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();
}

喜歡明確的等待或克服定時的“睡眠”。

關於一致性的說明

Herb Sutter提議改變async返回的future共享狀態的等待或阻塞。 這可能是MSVC行為的原因,可以看作已實施該提案。 我不確定該提案的最終結果是什么,或者它與C ++ 14的集成(或其中的一部分)。 至少從async返回的阻止future它看起來像MSVC行為沒有進入規范。

值得注意的是,§30.6.8/ 5中的措辭有所改變;

來自C ++ 11

在共享由此async調用創建的共享狀態的異步返回對象上調用等待函數應該阻塞,直到關聯的線程完成,就像加入一樣

致C ++ 14

在共享由此async調用創建的共享狀態的異步返回對象上調用等待函數應該阻塞,直到關聯的線程完成,就好像已加入, 或者超時

我不確定如何指定“超時”,我想它是實現定義的。

std::async返回未來 如果沒有調用getwait它的析構函數會阻塞:

如果滿足以下所有條件,它可能會阻塞:共享狀態是通過調用std :: async創建的,共享狀態尚未就緒,這是對共享狀態的最后一次引用。

從std :: asyncstd :: futures並不特別! 對於受試者的詳細治療。

main的末尾添加這兩行:

f1.wait();
f2.wait();

這將確保線程在main存在之前完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM