当使用以下示例代码时,我认为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),它不需要12us睡眠1秒,我合理确定!那么这里发生了什么,有没有tv_nsec循环?假设singed long
给出较小范围的正值(0到2147483647)而不是unsigned long
(0到4294967295),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
答案 0 :(得分:4)
在计算时间间隔时,您还需要考虑tv_sec
字段。
<强>更新强>
此外,CLOCK_PROCESS_CPUTIME_ID
测量用于此过程的CPU时间。如果使用nanosleep
得出,则此计时器不会递增。尝试例如而是CLOCK_MONOTONIC
。
答案 1 :(得分:2)
来自nano_sleep的手册:
未屏蔽的信号将导致nanosleep()提前终止睡眠,无论中断信号上的SA_RESTART值如何。
因此,您对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;
}