1

原則として、シリアルDispatchQueueは、送信されたタスクを次々と実行します。しかし、コンテキストスイッチが1つのタスク(たとえば、sleepと呼んでいる)で起動された場合はどうなりますか?キューはすぐに次のタスクを実行するか、現在のタスクが終了するのを待ちますか?このコードの場合シリアルDispatchQueueでコンテキストスイッチが起動された場合はどうなりますか?

q.async { 
    print("IN 1") 
    var i = 1 
    while i < 10 { 
    Thread.sleep(forTimeInterval: 0.1) 
    i += 1 
    } 
    print("OUT of 1") 
} 

q.async { 
    print("IN 2") 
} 

の結果である:

// IN 1 -> OUT of 1 -> IN 2 ? 
// or IN 1 -> IN 2 -> OUT of 1 ? 

私が遊び場でコードを実行しようとしたが、それはsleep(およびThread.sleep)らしい遊び場内で動作しません。

答えて

0

原則として、シリアルDispatchQueueはサブミットされたタスクを次々と実行します。しかし、コンテキストスイッチが1つのタスク(例えば、スリープを呼び出す)で起動された場合はどうでしょうか?キューはすぐに次のタスクを実行するか、現在のタスクが終了するのを待ちますか?

シリアルキューは、そのタスクが直列に提出されているという理由だけで(実際、ほとんどのタスクは通常でも並列キュー上で、ある)「シリアル」ではありませんが、タスクが保証されているために、一つ一つを完成しますそれらは提出された。

Thread.sleepは遊び場でうまく動作しますが、あなたのプレイグラウンドは早期に実行を終了しています。コントロールフローがページの最後に到達すると、Playgroundの実行が終了します。したがって、このような非同期タスクは、制御フローがページの最後に到達する前に実行された場合にのみ終了しますが、これはほとんど起こりません。

(マニュアル終了まで)無期限に実行遊び場を維持するために、使用:

import PlaygroundSupport 
PlaygroundPage.current.needsIndefiniteExecution = true 
+0

実際。 PlaygroundSupportのヒントをありがとう! – NeoWang

4

シリアルキューは、前の終了するまで次のブロックの実行を開始しません。コンテキストの切り替えはこれに影響しません。シリアルキューにサブミットされたブロック内のsleepを呼び出すと、スリープが終了してブロックが実行を再開できるようになるまでキューがブロックされます。結果はIN 1 -> OUT of 1 -> IN 2になります。

一般に、キューにサブミットされたブロックでブロックするもの(sleepなど)はスレッド全体をブロックし、libdispatchを他の作業に使用できないようにしたいので注意してください。 libdispatchは作業を続けるために必要に応じて新しいスレッドを回転させますが、生成するスレッドの数には限界があります。

関連する問題