0

これを参照フレームとして使用すると、次の例が {couldnt} / {wouldnt} の結果、GCD スレッド プールがメイン スレッドで排他的に実行される理由はありますか?

int main()
{
    dispatch_queue_t myQueue = dispatch_queue_create("myQ",NULL); // create serial queue

    //
    dispatch_sync(myQueue, ^{/*some simple block*/});
    ....
    dispatch_sync(myQueue, ^{/*some simple block*/});
} 

私の理解では、GCD は可能な場合はパフォーマンスを最適化し、(有益な場合は) ブロックを使用可能なスレッドに渡します。ただし、これを xcode で監視すると、これがメイン スレッドで排他的に実行されている可能性があることがわかります。async2 番目のスレッドが使用されるのは、ディスパッチ呼び出しが行われるまでです。

いつ/なぜ2番目のスレッドが呼び出されるか、呼び出されないかを理解したいだけです。これより前は、2 番目のスレッドが常に呼び出されると想定していました。

4

1 に答える 1

0

dispatch_sync を使用してブロックをディスパッチしています。dispatch_sync は、ブロックの実行が完了するまで待機します。したがって、そのシリアル キューを同期目的で使用しない限り、何をしても無意味です。同時実行はあり得ません。逆に、シリアル キューで既に実行中のコードがあり、ブロックがすでにシリアル キューにディスパッチされている可能性がある場合、メイン スレッドは、実行中のブロックとそれ以降にディスパッチされたすべてのブロックが終了するまで待機し、ブロックが終了するまで待機する必要があります。 .

dispatch_async を呼び出すと、2 つのブロックがシリアル キューにディスパッチされ、(1 つの CPU を使用して) 次々に実行されますが、メイン スレッドは他の CPU を使用して他の処理を続けます。

並行キューに対して dispatch_async を呼び出すと、2 つのブロックが並行して実行されますが、メイン スレッドは最大 3 つの CPU を使用して他の処理を実行できます。

メインスレッドがブロックされている間、コードは別のスレッドでブロックを「公式に」実行します。スレッド スイッチはコストがかかるため、可能であれば使用を避けます。したがって、シリアル キューへの dispatch_sync は、キューが空かどうかをチェックし、空の場合は、キューのディスパッチをブロックし、呼び出しスレッドでブロックを実行してから、キューのブロックを解除します。動作は、ブロックがディスパッチされた場合とまったく同じですが、より高速に実行されます。

于 2015-02-18T22:31:56.343 に答える