[英]Deadlock when using std::async with future as member
我將我們的應用程序從Objective-C和Cocoa轉移到了C ++。 在Objective-C中,我經常使用Grand Central Dispatch和非常方便的dispatch_async函數。
轉到C ++ 11時,我發現std :: async是最接近的等效項。 我正在使用它的Scott Meyers變體,以確保它確實被異步調用:
template<typename F, typename... Ts>
inline auto NLA_async(F&& f, Ts&&... params)
{
return std::async(std::launch::async,
std::forward<F>(f),
std::forward<Ts>(params)...);
}
我了解到,如果未分配返回的future,則該函數實際上不會被異步調用,因為future d'tor將等待異步塊完成。
void foo()
{
NLA_async([]{ // run long task async });
// future returned from NLA_async not captured
// -> std::future d'tor waits for block to be finished
}
因此,我認為我只是將future分配給一個類成員,以便它在大多數情況下至少是異步調度的(不理想,但我認為是一種快速而骯臟的解決方法)。 到目前為止,效果很好。
但是,我遇到了一個尚不了解的僵局。 看起來該塊有可能同時執行兩次,在我的情況下會導致死鎖。
您可以在這里看看:
http://coliru.stacked-crooked.com/a/dc4fcbaff370f1b9
誰能解釋為什么同時執行兩次?
編輯:在我的特殊情況下,問題是在異步塊的末尾,代碼鎖定了一個互斥鎖,做了一些工作,然后解鎖了互斥鎖。 在這一點上,我們陷入僵局。 看起來正在運行的異步塊在完成之前就被刪除了,因為互斥鎖保持鎖定,盡管不應該這樣做(沒有return語句或任何可以解釋為什么不解鎖互斥鎖的東西)。
兩個線程異步運行的問題可能與以下事實有關:創建未來並將其分配給成員變量不會一步就發生。
首先,創建它並啟動線程。 然后,在等待第一個線程完成時將其分配給成員變量。
感謝Useless指出這一點!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.