3

出力を書き込むために X 秒ごとに実行する必要があるプログラムがあります。プログラムは、各出力間で断続的なポーリングと処理を行います。たとえば、私は 5 秒ごとに出力しているかもしれませんが、次の 5 秒のマークに到達するまで 0.1 秒ごとにポーリングを開始します。理論的には、プログラムは再起動までに数か月、場合によってはさらに長く実行されます。

ウォールクロックとの一貫性を保つために、X秒ごとに実行する必要があります。言い換えれば、時計のずれによって X 秒のマークからずれることは許されません。断続的なポーリングでまったく同じレベルの精度は必要ありませんが、1 秒よりも頻繁にポーリングしたいので、1 秒未満の精度を表すことができる構造体が必要です。

OS上で実行するという性質上、タイマーの実行には一定の不一致/遅延があり、正確にx秒で実行されることを保証できないことを認識しています。しかし、それは小さな正規分布にとどまっている限り問題ありません。私が望んでいないのは、ドリフトが一貫してどんどんずれていく時間を許すことです。

また、ポーリングの CPU コストをできる限り最小限に抑えたいと考えていますが、それは二次的な問題です。

このレベルの精度を最もよく提供できる、Linux で使用できるタイミング構造は何ですか? 配布に手間がかかるのでアプリケーションにboostを含めないようにしていますが、必要に応じて使用できます。そのため、標準の C++ ライブラリを使用する方法が好まれますが、Bosst の方が優れている場合は、それも知りたいです。

ありがとうございました。

-ps、c++11 を使用できません。それはオプションではないので、そこから構成を使用する方法はありません。

4

3 に答える 3

4

clock_gettimeclock_nanosleepは両方とも 1 秒未満の時間で動作し、 を使用すると、CLOCK_MONOTONICシステム時間 (NTP やadjtimexなど) の調整によるスキューを防ぐことができます。例えば、

long delay_ns = 250000000;
struct timespec next;
clock_gettime(CLOCK_MONOTONIC, &next);
while (1) {
    next.ts_nsec += delay_ns;
    next.ts_sec += ts_nsec / 1000000000;
    next.ts_nsec %= 1000000000;
    clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
    /* do something after the wait */
}

実際には、信号で早く帰ったのか、睡眠時間が長すぎてインターバルを飛ばしたのかを確認する必要があります。

nanosleepselectなどの他のスリープ方法では、時間間隔を指定して を使用することしかできCLOCK_REALTIMEません。これはシステム時間であり、変更される可能性があります。

于 2012-06-20T14:41:32.947 に答える
1

ジッターや時計のずれのない正確なタイミングが必要な場合は、GPS、原子時計、電波時計などの外部時刻源を用意してください。たとえば、このPDFに記載されている NTP 統合を参照してください。すべての NTP トリックは、NanoBSD (PDF にあります) と同様に Linux でも機能します。

于 2012-06-21T10:33:24.520 に答える
0

開始した時間を記録し、t_0任意の時点tで、i = (t - t_0)/X(整数除算)が前回実行したときの同じ量よりも大きい場合は、再度実行します。

たとえば、5 秒ごとに実行しているとします。時間 23 に開始した場合、i = 0, t_0 = 23. その後、時間 27 では(27 - 23)/5 = 0、まだ実行していません。しかし、次は時間 28 に(28 - 23)/5 = 1なると 0 より大きいので、実行します。

このようにして、大きなドリフトが発生する可能性のあるティックごとにカウンターに追加するのではなく、開始からの時間を絶対に計算するので、実行する正確な時間を知ることができます。

于 2012-06-20T14:18:28.633 に答える