2011-01-27 13 views
2

GCDは、CPUを最大限に活用するために必要な数だけスレッドを作成することを理解します。 dispatch_asyncを使って約30回のバックグラウンドタスクを実行するコードでは、アクティビティモニターでスレッド数が約30回ジャンプしています。私はそれがデュアルコアのPCなので、それは期待できませんでした。グランドセントラルディスパッチで作成するスレッドの数はいくつですか?

私は何かを誤解していると確信しています。誰かが何が起こっているか教えてもらえますか?

+1

ディスパッチされたブロック、ermはブロックされますか?つまり、彼らはファイルシステム/ネットワーキングI/Oをしますか? –

答えて

5

GCDがスレッドを追加してスレッドプールを増やす状況の1つは、I/O競合です。ディスパッチされたブロックがファイルシステムまたはネットワーキングI/Oを待つ場合、CPUを使用しないので、GCDはCPUがアイドルであり、さらにスレッドを処理できると考えます。

実際、ディスパッチされたブロックの性質によっては、I/O競合がさらに増加し​​、512ワーカースレッドの上限に達する可能性があります。 Mike Ashはこの状況についてblog postと書いています。

+0

ああ、面白いです。スレッドは 'AXUIElememt ...'関数を呼び出して他のアプリケーションを検査します。これは問題のアプリの協力が必要なようです(ただし、どういう仕組みになっているのか分かりません)。これはブロックの理由の背後にある可能性があります。 –

+1

詳しくは、ディスパッチには、リソースが別のスレッドによって解放されるのを待っているスレッドと、関係のないリソースを待ってブロックされたスレッドとを区別するメカニズムがありません。新しいスレッドを作成しないと、「プロバイダ」タスクが「コンシューマ」タスクの背後でブロックされるため、デッドロックが発生する可能性があります。ディスパッチシンク、ディスパッチセマフォーなどを使ってディスパッチを使用してブロックする場合、私はlibdispatchがあなたのスレッドのために「継続」を行い、スレッド自体を再利用すると信じています(おそらくそのスタックなどを節約することによって)。 –

+1

更なるアップデート。あなたが言ったことに基づいて、私はそれぞれのタスクが 'dispatch_sync(dispatch_get_main_queue()、...')コールを実行することを認識しましたが、これはもちろんほとんどの時間をブロックします。作成されたスレッドは大幅に減少しました。 –

関連する問題