5

A long time ago I had a bug in my program. The root cause was that the C function

sleep(60);

would on rare occasions sleep less than 60 seconds. Or the function did cause the thread to sleep more than 60 s, but the clock was changed automatically by the OS (this seems likely since bug was happening only on XX::00::00), aka it was manifesting itself rarely, and only on "round hour" (sleep shoudl have ended at >xh0m0s, it ended on x-1h59m59.99*s).
Then my project manager went on a rant how he said million times that we should only use timers, not sleep. From that time I accepted the notion that timers are more accurate than sleep(), but now I feel that I should ask for some more authoritative source. So :

  1. are timers more precise than sleep?
  2. (related) are they deep down(on the OS level) implemented using different methods?
    I know timers are used to do callbacks, sleep just delays execution of current thread, Im talking about delay execution part of the implementation.

BTW OS was Linux, but I care about general answer if possible.

4

2 に答える 2

4

タイマーは睡眠よりも間違いなく正確です。スリープとは、タスクスケジューラがスレッドまたはプロセスを復活させるまでの大まかな目安です。システムクロックの変更、過負荷のタスクスケジューラなどは、実際にスリープする時間に影響します。

タイマーは時間をより正確に測定します。一般的に言えば、タイマーは時間を正確に測定します。タイマーには2種類あります。「time.h」の関数のようにシステムクロックに基づくものです。それらは、システムクロックの変更などの影響を受けます。たとえば、システム時刻を変更したり、夏時間から切り替えたり、マシンを一時停止したりした場合、実際に測定された時刻は実際の時刻と異なる場合があります。

他の種類のクロックは、CPUティックに基づく高解像度タイマーです。これらは、WindowsのQueryPerformanceTimerやLinuxのclock_gettime()のようなタイマーです。これらは単にCPUサイクルをカウントします。システムタイマーの変更による影響は受けませんが、次の2つの点で実世界の時刻から逸脱します。

  1. クロックの分解能が正確ではないため、この方法で時間を測定するとCPU時間がリアルタイムからずれてしまうため、時間が長期間にわたって歪むことになります。
  2. マシンが一時停止されている場合、CPUは停止し、タイマーはこれを考慮しません。

あなたがしたいのは、はるかに短い時間の睡眠と適切な解像度の時計を使用することです。例えば。数分未満の睡眠が必要な場合は、高解像度タイマーを使用する必要があります。必要な回数の100倍の頻度で睡眠をとり、睡眠が戻るたびに経過時間をチェックして、適切な時間が経過したかどうかを確認します。数分以上眠る必要がある場合は、同じことを行いますが、time.hの関数を使用して経過時間を確認します。

時間に対して100%正確である必要がある場合は、特殊なハードウェアが必要になる場合があります。または、海軍の原子時計のように、オンラインタイムサーバーに対して定期的にリアルタイムでチェックする必要があります。(http://tycho.usno.navy.mil/ntp.html

于 2012-06-28T17:14:26.007 に答える
2

アプリケーションをスリープ状態にする機能を提供するCまたはC++標準には何もないという単純な理由から、一般的な答えはありません。したがって、議論は本質的にOSに依存することになります。

UNIXsleep()関数の粒度は粗いです。また、より細かい粒度を持つものもusleep()あります。nanosleep()この関数select()を使用して、アプリケーションをスリープ状態にすることもできます。タイムアウトを指定するだけで、ファイル記述子は指定しません。

注1:、、、 itimers、およびアラーム間の相互作用は指定されていませんsleep()usleep()nanosleep()

注2:これらのメカニズムのいずれにも原子時計の精度があると期待しないでください。

于 2012-06-28T17:01:18.497 に答える