2016-04-27 40 views
0

如果我說有時可能發生主線程可能忙於某些global_queue任務?是否有可能在全局隊列上使用dispatch_async運行的塊在主線程上執行?

例如。我有一些任務要執行,我使用以下語句之一:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) { 
     // task 1 
    } 

// or 

    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) { 
     // task 2 
    } 

是否有可能在主線程中意外獲取此任務?或者這是不可能的,因爲主線程鎖定全局隊列? 謝謝!

+0

你試過了嗎?順便說一句,這完全消除了後臺任務的概念。保持主線程儘可能自由。一次只能在主線程上運行一件事情。如果它正在處理某些「背景」內容,則會被阻止;它不會更新用戶界面,它不會響應輸入,如果時間過長,應用程序將會被殺死。 – Eiko

+0

是的,我知道。但是,如果主線程閒置,它可以從global_queue獲取任務嗎? –

+0

我會說這將是一個實施過程中的巨大錯誤,不會發生。 – Eiko

回答

4

如果您在全局隊列上進行分派,它將在全局隊列上運行。如果您派遣到主隊列,它將運行在主隊列上。如果您派發到您自己創建的隊列,它將在該隊列上運行。

你問:「但是如果主線程空閒,它可以從global_queue獲取任務」。不,那會完全忽略這一點。如果主隊列處於空閒狀態,那麼所有的CPU都可以運行後臺任務,所以後臺線程運行得更快。主隊列從另一個隊列中取任務是沒有意義的,也是錯誤的。

+0

您正在對文檔不支持的GCD實施做出聲明,並暗示可隨時更改而不發出警告的實施細節。 – ipmcc

+1

@ipmcc,這是基本的併發。 gnasher是正確的。 –

+0

GCD文檔從不說將任務提交到後臺GCD隊列不會導致您的計算機爆發火焰。據瞭解。 –

1

實際上,這不應該發生,但是當你通過指定一個QOS類來獲得一個隊列時,嚴格來說,你得到的是一個實現細節,並且你不應該依賴它作爲一個特定的隊列或者不是特定隊列)。此外,任何給定隊列使用哪些線程來滿足入隊的工作是也是的實現細節。

但實際上,我不希望看到在主線程上執行QOS_CLASS_BACKGROUNDQOS_CLASS_UTILITY的工作排隊。

如果你想說服自己,你可以檢查從dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) == dispatch_get_main_queue()返回的隊列,同樣在你的工作單元內,你可以檢查[NSThread isMainThread]看看你是否在主線程上執行。

+0

謝謝,但QOS_CLASS_USER_INITIATED或QOS_CLASS_USER_INTERACITVE等其他QoS會發生這種情況嗎? –

+0

那個,我不太確定,但即使我觀察到它發生了,它仍然是一個實現細節。 :)給它一個快速測試,看起來,不,阻止'dispatch_async'到'QOS_CLASS_USER_INTERACTIVE'和'QOS_CLASS_USER_INITIATED'不在主線程上執行。 – ipmcc

+0

dispatch_get_global_queue _always_返回一個全局隊列,沒有別的。這將完全搞砸了返回其他任何東西。 – gnasher729

相關問題