2

たとえば、サーバーからデータをダウンロードする必要がある100個のオブジェクトにGCDを利用したいと思います。これらのオブジェクトをループして、次のように呼び出すとします。

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(q, ^{
    // Download data;
});

それらのブロックはインテリジェントにキューに入れられて効率的に実行されるでしょうか? それとも、メモリの問題、パフォーマンスの問題、さらには競合状態に陥るでしょうか?

私の2セントは、名前が示すようにブロックがキューに入れられ、ダウンロードが一度に1つずつ開始されることです。すべてのダウンロードが完了する前にアプリケーションが終了した場合、適切にクリーンアップしている限り、問題はないはずです.

ただし、別のボーナス質問:

たとえば、3 ~ 5 個のキューを作成し、キュー間でダウンロードを分散することにより、一度に複数のファイルをダウンロードすると、さらにメリットがありますか?


この機能を実装した後、受け入れられた回答が完全ではないか、ポイントを逃したようです。GCD によってディスパッチできるスレッドの最大数 (~64) があるため、コンカレントキューであるグローバル キューでブロックをディスパッチすると、問題が発生する可能性があります。これは、操作ごとにスレッドを生成する必要があるため、同時キューにのみ当てはまります。dispatch_asyncただし、独自のキューを作成すると、そのキューは、が呼び出された場合でもブロックを 1 つずつ実行するシーケンシャル キューになります。このようにして、キューが 1 つのスレッドのみを生成し、操作をキューに入れ、スレッド制限の問題に達することがないことを確認できます。

4

2 に答える 2

4

最初の一連の質問に対処します。つまり、「これらのブロックはインテリジェントにキューに入れられて効率的に実行されますか、それともメモリの問題、パフォーマンスの問題、または競合状態に遭遇するでしょうか」.

私の答え:

  1. これらのブロックはインテリジェントにキューに入れられ、効率的に実行されますか: はい、間違いなく実行されます。

  2. メモリの問題やパフォーマンスの問題が発生する可能性がありますか? これは状況によって異なります。非同期メソッドを呼び出しているため、最初のダウンロード操作の完了後に 2 番目のダウンロード操作が開始されることは保証されません。画像またはビデオをダウンロードしている場合、CFDATA または CFDATA(store) の問題 (処理可能) が原因で、メモリ不足の問題が発生する可能性があります。

  3. または競合状態 : スレッドを切り替える方法とタイミングをよく知っていれば、競合状態に陥ることはありません。例:クラスデリゲートをダウンロードする場合、メインスレッドで呼び出す必要がある場合は、NSURLConnection のようにメインスレッドで接続を開始する必要があります。ダウンロード後に UI 要素を処理している場合でも、スレッドを切り替える必要があります。そうしないと、競合状態やデッドロックは発生しません。

2 番目の質問に答えると、「たとえば 3 ~ 5 個のキューを作成し、キュー間でダウンロードを分散することで、一度に複数のファイルをダウンロードした場合、より多くのメリットがありますか?」

もし私があなたの立場にいたら、何百ものオブジェクトに対して単一のキューを使用していたでしょう。私はこのような状況にあり、私の場合、何千ものファイルをダウンロードする必要があります。一度に 1 つのファイルをダウンロードし、クリーンアップを行ってから先に進みます。何百ものファイルをダウンロードする場合と同様に、0.1 MB の余分な割り当てでもパフォーマンスの問題が発生します。

于 2013-11-10T04:48:56.713 に答える
0

MacOS X および iOS (O'Reilly) での並行プログラミングから:

ここに画像の説明を入力

于 2016-11-05T07:32:40.800 に答える