2017-02-08 29 views
1

當我運行下面的操場我注意到默認調度隊列似乎是叫OS_dispatch_queue_serial一個串行隊列Swift 3:爲什麼OS_dispatch_queue_serial是默認隊列?

這是爲什麼?

在這種情況下,我對異步同步語義使用混亂,在這種情況下,他們似乎是同步和連續行爲。

我錯了嗎? 我在混淆與同步的連續?

enter image description here

運行代碼之前我期待實現如下:

Hello World 
Hello Moon 

world * (or Moon) 
Moon * (or world) 
// Note: here I assumed that async meant that the codes in the block would have been run in parallel to each other and that this would have meant that either world or Moon would have been printed depending on **race conditions** 

Hello World 
world 
Hello Moon 
Moon 

遊樂場代碼:

import Foundation 
import PlaygroundSupport 

PlaygroundPage.current.needsIndefiniteExecution = true 

let queue = DispatchQueue(label: "com.test.myqueue") 

queue.async { 
    print("Hello World") 
    sleep(2) 
    print("world") 
} 
queue.async { 
    print("Hello Moon") 
    sleep(1) 
    print("Moon") 
} 

queue.sync { 
    print("Hello World") 
    sleep(2) 
    print("world") 
} 

queue.sync { 
    print("Hello Moon") 
    sleep(1) 
    print("Moon") 
} 

任何幫助瞭解這更快的將是巨大的。

回答

2

您正在混淆同步與異步,串行與並行。它們是正交的。讓我看看我能不能解釋一下:

同步異步描述相對於排隊洱排隊的塊的行爲。

串行平行描述相對於彼此排隊的塊的行爲。

串行隊列一次執行一個排入其中的塊。無論塊是同步還是異步排隊,情況都是如此。

並行隊列一次執行排入隊列的事物N,其中N可能(但不一定)大於1.無論塊是同步隊列還是異步隊列,這都是真的。

如果同步排隊塊,排隊線程將停止,直到塊的執行完成(可能在另一個線程上)。無論隊列是串行還是並行,情況都是如此。

如果排隊塊異步,入隊線程繼續,塊執行(最有可能在另一個線程)後的一定時間,可能同時入隊的線程上的代碼仍然在運行。無論隊列是串行還是並行,情況都是如此。

至於爲什麼serial是默認的,很難說,但我的猜測是,這是因爲'串行隊列'更符合單詞'queue'的字典定義。

+1

最初(的iOS 4/OS X 10.6),你不能在GCD創建併發隊列。有系統併發隊列,但你不能再創建。在iOS 4.3/OS X 10.7中,他們添加了創建併發隊列的功能,但將串行隊列保留爲默認隊列。在實踐中,我通常很少發現有用的定製併發隊列,通常在實現生產者/消費者模式時(https://github.com/iosptl/ios7ptl/blob/master/ch23-AdvGCD/ProducerConsumer/ProducerConsumer/ViewController.m) 。系統通常就足夠了。通常當你製作一個自定義隊列時,就是序列化訪問。 –

+1

(即使我列出的例子並不需要一個自定義的併發隊列;對於其中一個系統隊列來說也沒有問題,所以它比以前更少見:D但是很多使用串行隊列的東西都是不可信的如果串行隊列使用FIFO和非串行隊列(併發)使用隨機執行標準,那麼將無法完成定製任務。) –

2

隊列有兩種形式:

  • 串行 - 運行在一個時間塊一個
  • 併發 - 運行塊一次一個

調度塊隊列超過有兩種口味:

  • 同步 - 立即執行此操作我將等待
  • 異步 - 稍後再進行一段時間。

所以在你的例子中你創建了一個串行隊列(一次只能運行一個塊)。然後你將4個塊分派給那個隊列。其中一些運行在某個點(異步)和一些立即運行(同步)。但是因爲隊列是串行的,所以你一次只能運行其中的一個。因此,在下面的插圖中,串行隊列將在其開始塊2之前完成塊1.併發隊列同時啓動塊1和塊2,並且它們都在同一時間運行。

Illustration of serial vs concurrent queues

+0

因此,串行隊列使用FIFO和非串行隊列(併發)使用隨機執行標準? (例如一小段代碼塊1,一小塊代碼塊2 ..) – mm24

+0

看到我添加的圖像。併發隊列不交替或交錯塊1和2,它獨立地同時執行兩個塊。 –