5

C++ で VC2010 を使用して、Windows 7 でデータ取得アプリケーションを実行しています。1 つのスレッドは、約 0.9 秒のタイムアウトを持つハードウェアをキープアライブするために 0.2 秒ごとに変更を送信するハートビートです。通常、ハートビート コールには 10 ~ 20 ミリ秒かかり、スレッドは残りの時間をスリープ状態に費やします。

ただし、1 ~ 2 秒の遅延が発生し、ハードウェアが一時的にシャットダウンすることがあります。ハートビート スレッドは、THREAD_PRIORITY_TIME_CRITICAL で実行されています。これは、通常の優先度のプロセスでは 15 です。他のスレッドは通常の優先度で実行されていますが、DLL を使用して他のハードウェアを制御していて、Process Explorer でレベル 15 で実行されているいくつかのスレッドを開始していることに気付きました。

速度低下の原因を突き止めることはできませんが、アプリケーションの他のスレッドで、これが発生したときに同じ種類の遅延が発生しています。非常に単純なコードですが、ハートビート コードにいくつかの最適化を行いましたが、それでも時折エラーが発生します。ここで、プロセス全体に REALTIME_PRIORITY_CLASS を指定せずに、このスレッドの優先度を 15 を超えて上げることができるかどうか疑問に思います。そうでない場合、REALTIME_PRIORITY_CLASS を使用する際に知っておくべき欠点はありますか? (このハートビート スレッドを除いて、アプリケーションの残りの部分にはリアルタイムのタイミングは必要ありません。)

(または、これらの速度低下を追跡する方法について何かアイデアを持っている人はいますか...ソースが私のアプリにあるのか、システムのどこかにあるのかわかりません)。

更新: したがって、実際に 31 を AfxBeginThread 呼び出しに渡そうとしたことはなく、その値を無視し、THREAD_PRIORITY_TIME_CRITICAL で取得した 15 ではなくスレッドを通常の優先度に設定することがわかりました。

更新: ディスク デフラグ ツールの実行は、多くのスレッド遅延を引き起こす良い方法であることが判明しました。REALTIME_PRIORITY_CLASS でプロセスを実行し、THREAD_PRIORITY_TIME_CRITICAL (レベル 31) でハートビート スレッドを実行しても、役に立たないようです。次に試すことは、AvSetMmThreadCharacteristics("Pro Audio") の呼び出しです。

更新: ハートビート スレッドを "Pro Audio" としてスケジュールすると、スレッドの優先度が 15 (ベース = 1、ダイナミック = 24) を超えて増加しますが、デフラグが実行されているときは実際の違いはないようです。速度低下の多くをディスク デフラグ ツールと関連付けることができたので、毎週のスキャンをオフにしました。まだいくつかの遅延を説明できないため、ウォッチドッグ タイムアウトを 5 ~ 10 秒に増やします。

4

3 に答える 3

4

できたとしても、優先度を上げることは役に立ちません。最も優先度の高い実行可能なスレッドが常にプロセッサを取得します。

ほとんどの場合、割り込みが無効になっている間に拡張割り込み処理が発生しています。割り込みは、どのスレッドよりも高い優先度で効果的に機能します。

ビデオ、ネットワーク、ディスク、シリアル、USB などの可能性があります。選択的に無効にするか、別のドライバーを使用して、問題のシステムの躊躇が影響を受けるかどうかを確認するには、ある程度の洞察が必要です。それを見つけたら、それを防ぐ方法を考え出すことは、それが何であるかに応じて、些細なことから不可能なことまでさまざまです.

システムについての知識がなければ、なんとも言えません。別のPCで実行してみましたか?

于 2012-05-17T16:11:14.403 に答える
1

公式には、REALTIME_PRIORITY_CLASS を持たないプロセスで REALTIME スレッドを使用することはできません。

非公式に、文書化されていない参照で遊ぶことができNtSetInformationThread ます: http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/NtSetInformationThread.html

しかし、私はそれを試していないので、これに関するこれ以上の情報はありません。

一方、前に述べたように、スレッドのクォンタムが期限切れになるときに、OS が時間がかからないことを確認することはできません。多くの場合、特定の適切に記述されていないドライバーが、このような遅延の原因となります。

それ以外の場合は、カーネル部分の動作に問題があるかどうかを通知できるソフトウェアがあります: http://www.thesycon.de/deu/latency_check.shtml

于 2012-07-31T15:24:27.200 に答える
0

CreateWaitableTimer() & SetWaitableTimer() を使用してみて、同じプリエンプションの問題が発生するかどうかを確認します。

于 2012-05-30T16:18:32.737 に答える