簡體   English   中英

使用std :: async並以future作為成員時出現死鎖

[英]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.

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