2017-04-26 224 views
3

我工作在Java上,並且非常清楚線程和線程池的工作情況。線程池:DispatchQueue.main.async

我想知道是否有人可以解釋如何創建線程的工作,並在線程池中分配空間在swift?

此外,沒有

Dispatch.main.async { 
// some code 
} 

創建一個新的線程或異步執行任務?

預先感謝=)

回答

3

您的代碼隊列在主隊列(Dispatch.main)的代碼塊,並立即(.async)返回,在執行代碼之前。

您無法控制隊列使用哪個線程。即使你創建了自己的隊列:

let serialQueue = DispatchQueue(label: "queuename") 
serialQueue.async { 
    ... 
} 

你不知道你的代碼將在哪個線程上運行。


更新:

由於正確地Paulw11的評論指出,

...如果你在主隊列調度任務,這是保證在主線程上執行。如果您在任何其他隊列上派發任務,則不知道它將在哪個線程上執行;它可能會在主線程或其他線程上執行。

+5

有一點,如果您在主隊列上派發任務,則保證在主線程上執行。如果您在任何其他隊列上派發任務,則不知道它將在哪個線程上執行;它可能會在主線程或其他線程上執行。 – Paulw11

+0

@ Paulw11正確。更新了答案。 – shallowThought

6

隊列和線程是單獨的概念。隊列被排序(有時是優先級)塊序列執行。作爲(大部分)實現細節,塊必須被調度到線程才能執行,但這不是它們的主要觀點。

因此Dispatch.main.async將一個塊調度(追加)到主隊列中。主隊列是串行的,並且有點特別,因爲它可以在主線程上獨佔運行(正如Paulw11所指出的那樣)。它也承諾與主要的runloop相關聯。理解這種「將隊列附加到隊列」的概念是至關重要的,因爲它對你在隊列中設計事物的方式以及你在線程中設計事物的方式有重大影響。 async並不意味着「現在就開始運行」。這意味着「堅持在隊列中,但不要等待它。」

作爲設計如何不同的一個很好的例子,將一些東西放在隊列中並不意味着它會運行(即使沒有錯誤或死鎖)有史以來運行。暫停隊列以停止調度塊是可能的和有用的。將隊列綁定到其他隊列是可能的,這樣當隊列「計劃」某些內容時,它就會將其放入另一個隊列中,而不是執行它。有很多事情可以通過與「在後臺運行事件」無關的隊列來完成。您可以將完成處理程序附加到塊。您可以使用組來等待塊的集合。 GCD是考慮併發性的一種方式。並行性只是一個副作用。 (這個概念的一個很好的討論是Concurrency is not parallelism by Rob Pike它在Go中,但這些概念仍然適用。)

如果你調用Dispatch.main.async主隊列運行時,則該塊是絕對肯定執行,直到當前塊結束。在UIKit和AppKit中,「當前塊完成」通常意味着「您從OS調用的方法返回」。雖然沒有以這種方式實現,但您可以假裝每次從OS調用它時,都會調用Dispatch.main.async

這也是您爲什麼決不能從主隊列中調用Dispatch.main.sync(注意sync)的原因。該塊會等待你回來,你會等到塊完成。經典的僵局。

通常,線程池不是iOS中的業務。這是一個實現細節。有時你需要考慮性能方面的原因,但是如果你對此有太多的想法,那麼你可能會錯誤地設計你的併發性。

如果您來自Java,您一定要在併發編程指南中閱讀Migrating Away From Threads。它是如何重新考慮隊列中基於線程的模式的權威資源。