[英]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
返回未來 。 如果沒有調用get
或wait
它的析構函數會阻塞:
如果滿足以下所有條件,它可能會阻塞:共享狀態是通過調用std :: async創建的,共享狀態尚未就緒,這是對共享狀態的最后一次引用。
從std :: async看std :: futures並不特別! 對於受試者的詳細治療。
在main
的末尾添加這兩行:
f1.wait();
f2.wait();
這將確保線程在main
存在之前完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.