私はJavaで作業していましたが、スレッドとスレッドプールの作業でかなり明確でした。スレッドプール:DispatchQueue.main.async
私は誰でもスレッドの作成方法を説明し、スレッドプール内のスペースをswiftで割り振ることができるのだろうかと思っていましたか?
はまた、
Dispatch.main.async {
// some code
}
は、新しいスレッドを作成するか、非同期タスクを実行していますか?事前に
感謝=)
私はJavaで作業していましたが、スレッドとスレッドプールの作業でかなり明確でした。スレッドプール:DispatchQueue.main.async
私は誰でもスレッドの作成方法を説明し、スレッドプール内のスペースをswiftで割り振ることができるのだろうかと思っていましたか?
はまた、
Dispatch.main.async {
// some code
}
は、新しいスレッドを作成するか、非同期タスクを実行していますか?事前に
感謝=)
あなたのコードは、メインキュー(Dispatch.main
)上のコードのブロックをキューイングし、コードを実行する前に、(.async
)すぐに戻ります。
キューで使用されているスレッドを制御することはできません。独自のキューを作成しても、コードが実行されるスレッドはわかりません。
更新:
として正しくあなたがメインキューにタスクをディスパッチあれば、メインスレッド上で実行することが保証されて...、コメントにPaulw11によって
を述べました。他のキューにタスクをディスパッチすると、そのスレッドが実行されるスレッドがわからなくなります。メインスレッドまたは他のスレッドで実行される可能性があります。
キューとスレッドは別々の概念です。キューは、実行されるブロックの順序付けられた(時には優先順位付けされた)シーケンスです。実装の詳細(大部分)は、実行するためにブロックをスレッドにスケジューリングする必要がありますが、これはその主なポイントではありません。
したがってDispatch.main.async
は、ブロックをメインキューにディスパッチ(追加)します。メインキューはシリアルであり、メインスレッド(Paulw11が指摘する)で排他的に実行されることも約束されている点で多少特別です。それはまた、メインrunloopに関連付けられることを約束します。これが「キューにブロックを追加する」という概念は、キュー内のものの設計方法やスレッドの設計方法に大きな影響を与えるため、非常に重要です。 async
は「これを今すぐ実行する」という意味ではありません。それは「これを待ち行列に張りますが、それを待たない」という意味です。
デザインがどのように異なるかの良い例として、キューに何かを配置しても、が実行されることはありません(バグやデッドロックがなくても)。待ち行列を中断してブロックのスケジューリングを停止することは可能であり、有用である。待ち行列を他の待ち行列に結びつけることができるので、ある待ち行列が何か「予定」を立てると、それを実行するのではなく別の待ち行列に入れるだけです。 「バックグラウンドで実行する」とは関係のない待ち行列でできることはたくさんあります。ブロックに完了ハンドラをアタッチすることができます。グループを使ってブロックの集合を待つことができます。 GCDは並行性を考える方法です。並列性は単なる副次的な利点です。 (このコンセプトの偉大な議論はConcurrency is not parallelism by Rob Pikeです。それはGoにありますが、コンセプトはそのまま適用されます。)
メインキュー上で実行中にDispatch.main.async
を呼び出す場合、そのブロックはに絶対確実ではありません現在ブロックが終了するまで実行されます。 UIKitとAppKitでは、「現在のブロックが終了しました」とは、しばしば「あなたがOSによって呼び出されたメソッドから戻る」ことを意味します。この方法では実装されませんが、OSから呼び出されるたびに、Dispatch.main.async
への呼び出しでラップされているようなふりをすることができます。
したがって、Dispatch.main.sync
(注:sync
)をメインキューから決して呼び出さないでください。そのブロックはあなたが戻ってくるのを待って、ブロックが終了するまで待つでしょう。古典的なデッドロック。
通常、スレッドプールはiOSではあなたのビジネスではありません。実装の詳細です。時にはパフォーマンス上の理由から考える必要があることもありますが、あまりにも多くのことを考えているのであれば、おそらく並行性を間違って設計していることでしょう。
Javaを使用している場合は、「並行処理プログラミングガイド」のMigrating Away From Threadsを必ず読んでください。これは、キュー内のスレッドベースのパターンを再考するための決定的なリソースです。
メイン・キューにタスクをディスパッチすると、メイン・スレッドで確実に実行されます。他のキューにタスクをディスパッチすると、そのスレッドが実行されるスレッドがわからなくなります。メインスレッドまたは他のスレッドで実行される可能性があります。 – Paulw11
@ Paulw11正しい。更新された答え。 – shallowThought