2009-05-21 15 views
11

WaitForSingleObject関数を使用して信号なしのイベントを待つと、指定されたタイムアウト時間より短い時間でWAIT_TIMEOUTが返される場合があります。タイムアウトを1000msに設定してコールをループするだけで、990msという低い期間(WinXPで動作)でコールが返ってきたことがわかりました。私はQueryPerformanceCounterを使用して、システムクロックに依存しない時間測定値を取得しているので、クロックドリフトは答えになるとは思わない。WaitForSingleObjectのタイムアウトの解決

この動作は私にとっては実用的な問題ではありませんが、より良く理解したいと思います。おおよそタイマーティックの解像度で動作しているようです。マイクロソフトはこの機能の精度に関する詳細を公開していますか?私はVistaでより高い精度を期待する必要がありますか?

+0

私は小さなテストを提案したいと思います:wait関数の前に 'sleep(0)'を入れてください。これはあなたの期待に応えるために行動を変える可能性が非常に高いです。また、 'QueryPerformanceCounter()'の結果を 'QueryPerformanceFrequency()'によって返される頻度を使って時間値に変換することは、その頻度が正確であることを意味します。与えられた周波数は定数として扱われます。しかし、ハードウェアには許容誤差があります。周波数には常にオフセットがあり、場合によっては熱ドリフトもあります。 – Arno

答えて

8

はい、WaitForSingleObjectは、タイマーのティック解像度を使用しますが、QueryPerformanceCounterのような高解像度タイマーは使用しません。

http://msdn.microsoft.com/en-us/library/ms687069(VS.85).aspx、「関数を待って」上のMSDNの資料では、この上で展開されます。

指定されたタイムアウト 間隔の精度は システムクロックの解像度に依存します。システムクロック は一定のレートで「チック」します。 タイムアウト間隔がシステムクロックの 解像度よりも小さい場合、 待機時間は、指定された時間の 未満にタイムアウトする可能性があります。 のタイムアウト間隔が ティックで2より小さい場合は、 は1と2ティックの間であれば のようになります。

この記事では、timeBeginPeriodを使用してシステムクロックの解像度を上げる方法についても説明しますが、これはお勧めしません。

私はいくつかの理由が考えられます。第1に、WaitForSingleObjectのほぼすべての使用例に対して、より高い解像度が必要とされない。高解像度タイマーを使用するには、カーネルがタイマーを絶えずポーリングする必要があります(カーネルコードが常に動作することが保証されていないため実行できません)。また頻繁に再プログラムして割り込みを生成する必要があります(WaitForSingleObjectが複数、プログラマブル割り込み)。

一方、WaitForSingleObject、SetWaitableTimer、およびSleepのために十分以上の解像度で常に更新可能なタイミングソースがあります。

関連する問題