簡體   English   中英

什么時候使用 std::launch::deferred?

[英]When to use std::launch::deferred?

安東尼威廉書中的台詞:

std::launch::deferred指示 function 調用將被推遲,直到將來調用wait()get()為止。

 X baz(X&); auto f7 = std::async(std::launch::deferred, baz, std::ref(x)); //run in wait() or get() //... f7.wait(); //invoke deferred function

與直接調用 ( baz(ref(x)) ) 相比,這段代碼的好處或區別是什么?

換句話說,在這里擁有未來有什么意義?

假設你有一個線程池。

線程池擁有一定數量的線程。 說10。

添加任務時,它們會返回未來,並且它們會排入池中。

池中的線程喚醒,抓取任務,處理它。

當您在該池中有10個任務等待隊列中的某個任務時會發生什么? 好吧,陷入僵局。

現在,如果我們從此池中返回延遲的未來,該怎么辦?

當你等待這個延期的未來它醒來時,檢查任務是否完成。 如果是這樣,它就會完成並返回。

接下來,如果任務在隊列中但尚未啟動,它會從隊列中竊取工作並在那里運行 ,然后返回。

最后,如果它是由隊列運行但沒有完成,它會做一些更復雜的事情。 (通常最常用的最簡單的版本是阻止任務,但這並不能解決某些病態情況)。

在任何情況下,現在如果隊列中的任務休眠等待隊列中的另一個任務完成但尚未排隊,我們仍然可以取得進展。


另一個用途是減少奧術。 假設我們有一些懶惰的值。

我們不是計算它們,而是將共享期貨與其中的計算步驟一起存儲。 現在任何需要它們的人只需要一個.get() 如果已經計算了該值,我們得到該值; 否則,我們計算它,然后得到它。

稍后,我們添加一個系統來做空閑或另一個線程的工作。 在某些情況下,這些取代了延遲的懶惰期貨,但在其他情況下卻沒有。

我認為,主要的好處是它可能在不同的線程中執行 - 實際上是未來的線程。 這允許在線程之間傳輸“工作單元” - 即線程1創建未來,而線程2調用wait它。

在我看來。 我閱讀了effective modern c++規則 35

Compared to thread-based programming, a task-based design spares you the travails
of manual thread management

這意味着 std::launch::deferred 是一個更糟糕的情況,當操作系統無法為您分配新線程時, baz function 仍然可以工作,但它作為延遲任務運行,而不是像pthread_create那樣返回失敗或拋出異常std::thread 像這樣:

terminate called after throwing an instance of 'std::system_error'
  what():  Resource temporarily unavailable

結論:

// same thread with called.
    std::async(std::launch::deferred, bax,..) = baz() 

// create a new thread to run baz(..) in case of OS have ability to allocate a new thread, otherwise same above 
    std::async(baz, ...) = std::async(std::launch::deferred| std::launch::async , baz, ...) != baz() ;

https://man7.org/linux/man-pages/man3/pthread_create.3p.html
https://godbolt.org/z/hYv7TW51q測試

暫無
暫無

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

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