1. ホーム
  2. ios

[解決済み] シリアルキューにおける dispatch_async と dispatch_sync の違い?

2022-07-05 18:47:57

質問

このようなシリアルキューを作成しました。

    dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);

とは何が違うのでしょうか? dispatch_async はこのように呼ばれます。

 dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
 dispatch_async(_serialQueue, ^{ /* TASK 2 */ });

そして dispatch_sync は、このシリアルキューでこのように呼び出されるのですか?

 dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
 dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });

私の理解では、どのディスパッチ方式であろうと TASK 1 が実行され、完了する前に TASK 2 の前に実行され、完了します。

どのように解決するのですか?

はい、そうです。シリアルキューを使用すると、タスクの連続実行が保証されます。唯一の違いは dispatch_sync はブロックが終了してから戻るだけですが dispatch_async はキューに追加された後に戻り、終了していない可能性があります。

このコードに対して

dispatch_async(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_async(_serialQueue, ^{ printf("3"); });
printf("4");

次のように表示されるかもしれません。 2413 または 2143 または 1234 しかし 1 の前に必ず 3

このコードでは

dispatch_sync(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_sync(_serialQueue, ^{ printf("3"); });
printf("4");

と表示されます。 1234


注:最初のコードでは プリント 1324 . なぜなら printf("3") はディスパッチされるからです。 の後に printf("2") が実行されます。また、タスクが実行されるのは の後に でしか実行できません。


タスクの実行時間は何も変わりません。このコードでは常に 12

dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); });
dispatch_async(_serialQueue, ^{ printf("2"); });

何が起こったかというと

  • スレッド1:時間のかかるタスク(タスク1)をシリアルキューにdispatch_asyncする。
  • スレッド2: タスク1の実行開始
  • スレッド1: 別のタスク(タスク2)をシリアルキューにdispatch_asyncする。
  • スレッド2:タスク1終了。タスク2の実行を開始。
  • スレッド2:タスク2終了。

と表示され、常に 12