8

私のアプリケーションには、バックグラウンドで動作するスレッドがいくつかあります。データベースに接続し、時間のかかる選択クエリを実行します。ほとんどの場合、これらのクエリはいくつかのレコードのみを返します。ただし、場合によっては、何万ものレコードが返されることがあります。これらはすべてループで処理されます。

このような状況は複数のスレッドで同時に発生する可能性があるため、これらのスレッドがデータを処理しているときに、アプリケーションで CPU 時間を 100% 使用したくありません。また、すべてのスレッドがプロセッサの時間を争うようにしたくもありません。したがって、これらのスレッドのループの各反復で Sleep() 関数を呼び出します。

ただし、スリープ時間を調整する方法がわかりません。ループを永遠に続けたくないので、スリープ期間が長すぎてはいけません。各反復 (各スレッド) で 2 ミリ秒に設定しました (なぜ 2ms ですか? - それは良い質問です:))。

一方、スリープ時間を延ばすことはできると思いましたが、sleep を呼び出すのは n 回の反復ごとに 1 回だけです (たとえば、50 回の反復ごとに Sleep(100) とします)。どのアプローチを選択すればよいですか? ループの 1 回の繰り返しには、それぞれ約 30 ミリ秒かかります (スリープなし)。

お知らせ下さい。

ありがとう!
マリウス。

4

4 に答える 4

10

Sleep()を呼び出しても意味がありません。取得できるすべての処理能力を使用して、スレッドを最適にスケジュールする方法をシステムに任せます。Sleep()を呼び出すと、余分なコンテキスト スイッチが発生し、スループットが低下するだけです。バックグラウンド処理がメイン スレッドや他のアプリケーションに干渉する場合は、それに応じてバックグラウンド スレッドの優先度を下げてください。

スレッドがコンシューマー向けに生成するデータの量を制限するためにスレッドをスリープさせたい場合は、プロデューサー/コンシューマー キューを調べてください。プロデューサー スレッドは、キューがいっぱいになったときに単純にブロックするようにします。この方法では、タイミングをいじる必要はまったくありません。

また、特に最新のプロセッサでは、最大の CPU を使用することは一般的に良いことです。ラップトップでさえ、短時間の高負荷がかかる方が、タスクに必要な時間を人工的に延長するよりも優れています。プロセッサ/システム全体がより早く低電力状態に入ることができるからです.

于 2009-06-06T21:39:54.757 に答える
4

優先順位の低いスレッドを作成し、スリープせずに動作させるようにすることをお勧めします。そうしないと、CPU の能力をフルに活用できません。たとえば、マルチコア/マルチ CPU システムの場合です。または、システムが 100% アイドル状態の場合: なぜ待機またはスリープする必要があるのでしょうか?

ただし、スリープが必要な場合は、既定の Windows タイムスライスのために、sleep(1) が 10 ~ 15 ミリ秒 (!) 待機することに注意してください。MMSystem.pas ユニットの timeBeginPeriod(1) を使用して、解像度を 1ms に設定できます :-) (これはシリアル通信に使用しました)。

于 2009-06-08T09:49:51.803 に答える
2

スレッドを制御するためにスリープを使用するよりも良いアプローチがあるかもしれません。データベース呼び出しは処理のために1〜1000のレコードを返す可能性があるため、アプリケーションを2つのレイヤーに分割し、メッセージキューを使用してリクエストをバッファリングすることが理にかなっている場合があります。アプリがデータサービスを呼び出すと、データサービスはクエリを実行し、個々のデータメッセージ(またはメッセージのブロックなど)をキューにディスパッチします。その後、アプリはメッセージを処理するために適切な数のスレッドを作成できます。スレッドが多いということは、CPUを犠牲にして処理が速くなることを意味しますが、これを調整して適切なバランスをとることができます。

于 2009-06-06T21:30:13.403 に答える
1

WinApi.Windows の Sleep() の代わりに、System.Classes の TThread.Sleep() を使用します。

// Winapi.Windows contains GetTickCount and Sleep
// System.Classes contains TThread (universal option) // TThread.GetTickCount() // TThread.Sleep()
uses System.Types, System.Classes, Vcl.Forms;

// 次に、プロセスで次を使用します

TThread.Sleep(0);

Application.ProcessMessages(); // clear all Vcl messages  // part of Vcl.Forms
CheckSynchronize(); // check all threaded events
于 2016-06-17T19:14:34.357 に答える