以下代码定期睡眠到预期时间点(ts),并立即获取系统时间(tm2)。为什么ts和tm2之间有一个固定的时间误差(~52 is ),因为两个时间点相邻。
运行环境是一个实时修补的linux,如果我改变周期时间间隔的大小,固定的时间误差几乎不会改变。
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define US 100 /* sleep US micro-seconds */
#define LOOP 20
double delayed[LOOP];
int main(void)
{
int loop = 0;
struct timespec tm1, tm2, tm2_old;
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &tm1);
ts.tv_sec = tm1.tv_sec;
ts.tv_nsec = tm1.tv_nsec;
while(1){
ts.tv_nsec = ts.tv_nsec + US * 1000L;
ts.tv_sec = ts.tv_sec + (ts.tv_nsec)/1000000000L;
ts.tv_nsec = (ts.tv_nsec)%1000000000;
clock_gettime(CLOCK_MONOTONIC, &tm1);
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL);
clock_gettime(CLOCK_MONOTONIC, &tm2);
delayed[loop] = (tm2.tv_sec-ts.tv_sec)*1000000.0 + \
(tm2.tv_nsec - ts.tv_nsec)/1000.0;
++loop;
if(loop >= LOOP) break;
}
for(int ii=0; ii<LOOP; ++ii){
printf("delayed %4.2f\n", delayed[ii]);
}
}运行结果:
delayed 55.62
delayed 53.02
delayed 52.47
delayed 52.30
delayed 52.25
delayed 52.32
delayed 52.30
delayed 52.45
delayed 52.28
delayed 52.29
delayed 52.16
delayed 52.16
delayed 52.19
delayed 52.28
delayed 52.26
delayed 52.23
delayed 52.24
delayed 52.26
delayed 52.32
delayed 52.15发布于 2020-07-03 14:28:56
timerslack是在Linux4.6中引入的,用于分组计时器到期,以满足CPU功耗的要求。
内核使用“当前”计时器松弛来对彼此相近的调用线程的计时器到期进行分组;因此,线程的计时器过期时间可能会晚到指定的纳秒数(但永远不会提前过期)。分组计时器呼气可以帮助减少CPU唤醒,以减少系统功耗。
用户可以通过编辑文件timerslack来更改/proc/{self}/timerslack_ns值。
https://stackoverflow.com/questions/62699029
复制相似问题