0

次のサンプルコードtv_nsec値を使用する場合、これは;にすぎないため、ループしていると思いますlong

#include <iostream>
using namespace std;
#include <time.h>

int main(int argc, char *argv[]) {
  timespec time1, time2;
  timespec timens = {0};
  timens.tv_sec = 1;

  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
  nanosleep(&timens, (struct timespec *)NULL);
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);

  cout << time1.tv_nsec << " : " << time2.tv_nsec << endl;
  cout << (time2.tv_nsec-time1.tv_nsec) << endl;
  return 0;
}

$ ./microtime 
2754095 : 2766801
12706

開始時間と終了時間の差は12706ns(12.7us)で、1秒間スリープするのに12usはかかりませんでした、私はそれをかなり確信しています!では、ここで何が起こったのでしょうか、tv_nsecはループしましたか?singed long(0〜4294967295)ではなく、より狭い範囲の正の値(0〜2147483647)を指定すると仮定するとunsigned long、2147483647ナノ秒はまだ2秒強です。

コードを次のように変更しても、一見無効な出力が表示されます。

timens.tv_sec = 0;
timens.tv_nsec = 100000;

$ ./microtime
2743552 : 2754327
10775

スリープ時間は100,000nsに設定されましたが、その出力によると、プログラムは10,000nsスリープしました。少し時間がかかることは承知していますが、1秒のような長い時間でも、100usのような短い時間でも、ここでは精度がないように見えるか、これらの値の間のどこかにあることを示しています。私は何か間違ったことをしていますか、これをどういうわけか間違って実装しましたか?clock_gettime()の呼び出しの間にイベントの実際の期間を取得できないのはなぜですか?

お時間をいただき、ありがとうございました。

アップデート

@Oli; 次のコードで提案をテストできますが、機能しないようです。

int main(int argc, char *argv[]) {
  timespec time1, time2;
  timespec timens = {0};
  timens.tv_sec = 1;
  timens.tv_nsec = 0;

  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
  nanosleep(&timens, (struct timespec *)NULL);
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);

  cout <<time1.tv_sec<<"s:"<<time1.tv_nsec<<"ns : "<<
         time2.tv_sec<<"s:"<<time2.tv_nsec<<"ns"<<endl;
  cout <<(time2.tv_nsec-time1.tv_nsec)<<endl;
  return 0;
}

$ ./microtime
0s:2801478ns : 0s:2813732ns
12254
4

2 に答える 2

4

tv_sec時間間隔を計算するときは、フィールドも考慮する必要があります。

アップデート

また、CLOCK_PROCESS_CPUTIME_IDこのプロセスに使用されるCPU時間を測定します。で譲歩した場合nanosleep、このタイマーは増加しません。CLOCK_MONOTONIC代わりに例えば試してみてください。

于 2012-05-13T14:38:14.573 に答える
2

nano_sleepのマニュアルから:

マスクされていない信号により、割り込み信号のSA_RESTART値に関係なく、nanosleep()はスリープを早期に終了します。

結果として、nanosleep()の使用法は単純になります。
これは次のようになります(ただし、これは大まかなアイデアを提供するためだけにテストされたものではありません)。

timespec requestedSleep = {0};
requestedSleep.tv_sec = 1;

timespec start = {0};
start = /* current real time */;

while( nanosleep(&requestedSleep, NULL) == -1)
{
    timespec end.t = {0};
    end = /* current real time */;

    updateRequestedSleepTime(requestedSleep, start, end);
    start = end;
}
于 2012-05-13T15:21:09.937 に答える