2017-02-08 4 views
1

は私がデフォルトディスパッチキューは、OS_dispatch_queue_serial呼ばシリアルキューように見えることに注意してください。スイフト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

同期と非同期、シリアルとパラレルが混在しています。彼らは直交しています。私はそれを説明することができるかどうか、私は見てみましょう:

同期非同期エンキュー-ERに対するキューに入れられたブロックの動作を説明します。

シリアルと平行互いにに対してエンキューブロックの挙動を記述する。

シリアルキューは、一度に1つずつエンキューされたブロックを実行します。これは、ブロックが同期的または非同期的にエンキューされたかどうかにかかわらず、真です。

並列キューは、一度にNにエンキューされたものを実行します。Nは、必ずしもそうではありませんが、必ずしもそうではありません。ブロックが同期または非同期にエンキューされたかどうかにかかわらず、

ブロックを同期してにエンキューすると、ブロックの実行が完了するまで(おそらく別のスレッドで)エンキューされているスレッドが停止します。キューがシリアルかパラレルかにかかわらず、これは真です。

あなたがブロック非同期をエンキュー場合エンキュースレッド上のコードがまだ実行されている可能性の一方で、ある程度の時間後に、エンキュースレッドが継続し、ブロック実行(別のスレッドで最も可能性が高いです)。キューがシリアルかパラレルかにかかわらず、これは真です。

なぜシリアルがデフォルトであるのかについては言うことはできませんが、私は、「シリアルキュー」は「キュー」という単語の辞書の定義に沿っているからです。

+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/ViewController.m)を実装するときに、カスタムの並行キューはほとんど役に立ちません。 。通常、システム1で十分です。通常、カスタムキューを作成すると、アクセスがシリアライズされます。 –

+1

(私が列挙した例でも、実際にはカスタムの並行キューは必要ありませんでしたが、それはシステムキューの1つでうまくいきましたので、それはまれです...:Dしかし、 –

2

キューは、2種類があります:

  • シリアル - 同時時間
  • でブロック1を実行します - キューにブロックを派遣、一度に複数の

が二つに来るブロックを実行します。フレーバー:

  • 同期 - これを今すぐ実行しますか?
  • async - これは後でしばらくお待ちください。

この例では、シリアルキューを作成します(一度に1ブロックしか実行しません)。次に、4つのブロックをそのキューにディスパッチします。それらのうちのいくつかは、ある時点(非同期)で実行され、すぐに実行されるもの(同期)があります。しかし、キューはシリアルなので、一度に1つだけ実行します。したがって、以下の図では、シリアル・キューはブロック2を開始する前にブロック1を完了します。同時キューはブロック1とブロック2を同時に開始し、両方が同時に実行されます。

Illustration of serial vs concurrent queues

+0

シリアルキューはFIFOと非シリアルキューを使用して(並行して)ランダム実行基準を使用しますか? (例えばコードブロック1の少し、コードブロック2の少し)。 – mm24

+0

画像を参照してください。並行キューは、ブロック1および2を交互にまたはインターリーブしません。両方のブロックを同時に独立して実行します。 –

関連する問題