这是 sleep() 的正确用法吗?
Is this a correct use of sleep()?
我正在使用这样的睡眠每 1/25 秒抓取一帧。 OS 是 Debian 6 armel。
#define VIDEO_FRAME_RATE 25.0f
while (RECORDING) {
sprintf(buffer, "Someting from a data struct that is updated\n");
fprintf(Output, buffer);
usecTosleep = (1.0f/VIDEO_FRAME_RATE) * 1000000;
usleep(usecToSleep);
}
问题:循环每1/25秒将缓冲区输出到输出文件描述符的保证是什么?
在 C 中有更好的方法吗?我需要它尽可能精确以防止漂移。
谢谢。
您的 "recording operation" 还需要一些时间...
所以你需要计算应该花在帧上的时间(usecTosleep = (1.0f/VIDEO_FRAME_RATE) * 1000000;
),然后计算操作实际花费的时间,相应地调整休眠时间:
usecTosleep = (1.0f/VIDEO_FRAME_RATE) * 1000000;
lastFrameUsec = 0;
while (RECORDING) {
sprintf(buffer, "Someting from a data struct that is updated\n");
fprintf(Output, buffer);
usecTosleep = (1.0f/VIDEO_FRAME_RATE) * 1000000;
// currentFrameUec - lastFrameUsec = actual time spending on operation
currentFrameUsec = getUsecElapsedFromStart();
actualSleep = usecToSleep - (currentFrameUsec - lastFrameUsec);
// If there's time to sleep left, sleep
if(actualSleep > 0){
usleep(actualSleep);
lastFrameUsec = getUsecElepasedFromStart();
} else {
lastFrameUsec = currentFrameUsec;
}
}
我不知道多平台 getUsecElapsedFromStart()
所以您可能必须自己实现,例如 this one。
int getUsecElapsedFromStart(const struct timespec *tstart)
{
struct timespec *tnow;
clock_gettime(CLOCK_MONOTONIC, &tnow);
return (int)((tnow tv_sec*10.0e9 + tnow.tv_nsec) -
(tstart.tv_ses*10.0e9 + tstart.tv_nsec));
}
clock_gettime(CLOCK_MONOTONIC, &tstart);
while(RECORDING){
// ...
currentFrameUsec = getUsecElapsedFromStart(&tstart);
}
回答你的第一个问题,没有这样的保证。 usleep()
只承诺只要您告诉它,它就会 至少 睡觉。但它可能会睡得更久:
The usleep() function suspends execution of the calling process for (at least) usec microseconds. The
sleep may be lengthened slightly by any system activity or by the time spent processing the call or by
the granularity of system timers.
我正在使用这样的睡眠每 1/25 秒抓取一帧。 OS 是 Debian 6 armel。
#define VIDEO_FRAME_RATE 25.0f
while (RECORDING) {
sprintf(buffer, "Someting from a data struct that is updated\n");
fprintf(Output, buffer);
usecTosleep = (1.0f/VIDEO_FRAME_RATE) * 1000000;
usleep(usecToSleep);
}
问题:循环每1/25秒将缓冲区输出到输出文件描述符的保证是什么?
在 C 中有更好的方法吗?我需要它尽可能精确以防止漂移。
谢谢。
您的 "recording operation" 还需要一些时间...
所以你需要计算应该花在帧上的时间(usecTosleep = (1.0f/VIDEO_FRAME_RATE) * 1000000;
),然后计算操作实际花费的时间,相应地调整休眠时间:
usecTosleep = (1.0f/VIDEO_FRAME_RATE) * 1000000;
lastFrameUsec = 0;
while (RECORDING) {
sprintf(buffer, "Someting from a data struct that is updated\n");
fprintf(Output, buffer);
usecTosleep = (1.0f/VIDEO_FRAME_RATE) * 1000000;
// currentFrameUec - lastFrameUsec = actual time spending on operation
currentFrameUsec = getUsecElapsedFromStart();
actualSleep = usecToSleep - (currentFrameUsec - lastFrameUsec);
// If there's time to sleep left, sleep
if(actualSleep > 0){
usleep(actualSleep);
lastFrameUsec = getUsecElepasedFromStart();
} else {
lastFrameUsec = currentFrameUsec;
}
}
我不知道多平台 getUsecElapsedFromStart()
所以您可能必须自己实现,例如 this one。
int getUsecElapsedFromStart(const struct timespec *tstart)
{
struct timespec *tnow;
clock_gettime(CLOCK_MONOTONIC, &tnow);
return (int)((tnow tv_sec*10.0e9 + tnow.tv_nsec) -
(tstart.tv_ses*10.0e9 + tstart.tv_nsec));
}
clock_gettime(CLOCK_MONOTONIC, &tstart);
while(RECORDING){
// ...
currentFrameUsec = getUsecElapsedFromStart(&tstart);
}
回答你的第一个问题,没有这样的保证。 usleep()
只承诺只要您告诉它,它就会 至少 睡觉。但它可能会睡得更久:
The usleep() function suspends execution of the calling process for (at least) usec microseconds. The
sleep may be lengthened slightly by any system activity or by the time spent processing the call or by
the granularity of system timers.