これはあまりにも複雑な考え方のように感じられますが、その説明の詳細はほとんど正しくはありません。具体的には、「現在のスレッドですぐに発生する」というのは正しくありません。
まず、戻ってみましょう。dispatch_async
とdispatch_sync
の区別は、現在のスレッドがそれを待っているかどうかだけです。しかし、シリアル・キューに何かをディスパッチするときは、GCD自身が選択した別のワーカー・スレッド上で実行されていると常に想像してください。はい、最適化として、時々dispatch_sync
は現在のスレッドを使用しますが、あなたはこの事実を保証するものではありません。
第2に、dispatch_sync
について議論するとき、あなたは「すぐに」実行していると言います。しかし、それは決して確実ではありません。あるスレッドがあるシリアルキューに対してdispatch_sync
を実行すると、そのスレッドは(a)そのシリアルキューで現在実行中のブロックが終了するまでブロックします。 (b)その直列待ち行列の他の待ち行列ブロックを実行して完了させる。明らかに、スレッドA自身がディスパッチしたブロックが実行されて完了します。
同期のためにシリアルキューを使用すると、メモリ内のオブジェクトへのスレッドセーフなアクセスが頻繁に発生するため、同期処理が非常に高速になるため、待機スレッドは一般に無視されます。そのディスパッチされたブロック(および以前のディスパッチされたブロック)は終了する。しかし、一般に、すぐに実行されると言うのは間違いです。 (常にすぐに実行できる場合は、アクセスを同期させるためのキューは必要ありません)。
今
私はあなたがスレッドセーフか、そのようないくつかの他の理由を確実にするためには、でなければならない、コードの一部のビットの話をしていると仮定する「臨界領域」に関するご質問の交渉は、同期。したがって、このコードを実行して同期させる場合、唯一の質問dispatch_sync
とdispatch_async
の違いは、現在のスレッドが待機する必要があるかどうかです。たとえば、あるモデルにdispatch_async
が書き込まれる可能性があります(処理を続行する前にモデルが更新されるのを待つ必要がないため)dispatch_sync
は一部のモデルから読み込みます(明らかに進めたくないので読み取り値が返されるまで)。
シンク/非同期パターンのさらなる最適化は、リーダライタパターンであり、同時読み取りは許可されていますが、同時書き込みは許可されていません。したがって、並行キューdispatch_barrier_async
を使用して書き込み(書き込みの場合はシリアルのような動作を実現)を行いますが、dispatch_sync
の場合は他の読み取り操作と並行してパフォーマンスが向上します。
出典
2017-02-04 01:18:38
Rob
クリティカルリージョンは、クリティカルセクションの別の名前です。https://en.wikipedia.org/wiki/Critical_section –
はい、それはあなたが意味すると思ったものです。 iOSでは、これを「同期」する必要があると言います。 [Threading Programming Guide:Synchronization](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW1)を参照してください。 )。しかし、これはGCDの前にあります。これについては、「同時プログラミングプログラミングガイド:ロックベースのコードを削除する」(https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/ThreadMigration/ThreadMigration.html#//apple_ref/doc/uid/TP40008091-CH105-SW3)。 – Rob
うん。だから、私は即座に物事を語ることに少しうんざりでしたが、私はそれが正しいことをしていた。幸いにも私は、Androidの実装のためのメッセージキューを1つに減らすことができると考えています。 –