1

TCP を使用して、LAN 上のサーバーから複数の大きなファイルを (とりわけ) ダウンロードするプログラムを作成しました。このプログラムは、Linux、MacOS/X、および一般に Windows でも問題なく動作します (GUI には Qt を使用し、ネットワークには直接ソケット呼び出しを使用します)。そして、それがなぜなのか、そしてそれに対して何ができるのかについて誰かが何か考えを持っているかどうか疑問に思っています.

ファイルをダウンロードするとき、私のプログラムは別の I/O スレッドを生成します。このスレッドは基本的にはループに留まり、TCP 経由でデータをダウンロードしてファイルに書き込み、QFile:write() への呼び出しごとに 128KB を書き込みます。通常、各ファイルの長さは数百メガバイトで、通常のダウンロード セッションでは、これらのファイルが数十個書き出されます。I/O スレッドは GUI スレッドとは独立して実行されるため、GUI のパフォーマンスに大きな影響を与えるとは考えていません。特に、マルチコア PC で実行している場合はそうではありません。

問題の PC は、2.40 GHz で動作し、4 GB の RAM を搭載した Core-2Duo Quad Q6600 です。Windows 7 Ultimate SP1、32 ビットを実行しています。ギガビット イーサネット接続を介してデータを受信し、232GB の内部 Hitachi ATA ドライブの NTFS フォーマットのブート パーティション上のファイルにデータを書き込みます。

症状としては、ダウンロード中に (一見ランダムに) プログラムの GUI が一度に 10 ~ 30 秒間応答しなくなり、ウィンドウのタイトル バーに "(応答なし)" が追加されることがよくあります。その後、症状は再び解消され、ダウンロードは再び正常に進行します。もう 1 つの症状は、ダウンロード中にデスクトップが非常に遅くなることです。たとえば、[スタート] ボタンをクリックすると、[スタート] メニューがほぼ瞬時に読み込まれるのではなく、30 秒ほどかかります。 .

タスク マネージャーには十分な空きメモリが表示されますが、4 つのコアのうちの 1 つで 100% の CPU 使用率の短いスパイクが表示されると同時に、問題が見られることに注意してください。

データはギガビット イーサネット経由で到着します。プログラムにデータを受信させて (ハード ドライブに書き込まずに) 破棄させると、マシンは汗をかくことなく約 96MB/秒の一定のダウンロード速度を維持できます。しかし、受信したデータをファイルに書き込むと、ダウンロード速度が約 37MB/秒に低下し、上記の症状が現れ始めます。

興味深いのは、好奇心のために、イベント ループの開始直前に、I/O スレッドのエントリ関数に次の呼び出しを追加したことです。

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);

すると、「(応答なし)」の症状はなくなりましたが、ダウンロード速度が約 25MB/秒に低下しました。

だから私の質問は:

  • ハードドライブの書き込み負荷が高いときに、GUI が散発的にハングアップする原因を知っている人はいますか?

  • マシンにアイドル状態のコアが 3 つあるのに、I/O スレッドの優先順位を下げるとダウンロード速度が大幅に低下するのはなぜですか? この状況では、優先度の低いスレッドでも十分な CPU を利用できると思います。

  • Windows のデスクトップの応答性やアプリの GUI の応答性に問題を引き起こすことなく、最大のダウンロード レートを取得する方法はありますか?

4

1 に答える 1

0

コードを見ずに答えるのは難しいですが、これはプロセッサに関連するものであり、ダウンロードスレッドが他のスレッドが他の操作を実行するためのスペースを残していないという事実のようです.

それは決して待っていないようで、ネットワークカードのドライバがうまく書かれていないようです. データが入っていないときに、スレッドがアイドル状態になっていますか? シングル プロセッサの OS では、 for (;;) {} は 100% の CPU を消費し、カーネルと継続的に通信する場合、特にバグや非常に悪い動作がある場合、他のプロセスまたは他のスレッドを停止する可能性があります。あなたの場合、いくつかのネットワークカードドライバーで。

おそらく、スレッドの優先順位を通常より低く設定すると、OS にスレッドの使用頻度を下げるように求めていることになります。コードを確認してください。何か忘れているのではないでしょうか?

sleep(0) を追加して OS を強制的に別のスレッドに譲ることで状況が改善するかどうかを確認しますが、これは一時的な修正であり、スレッドが 100% の CPU を消費している場合はその理由を見つける必要があります。

于 2011-10-21T23:24:57.700 に答える