【问题标题】:Is this a correct use of sleep()?这是对 sleep() 的正确使用吗?
【发布时间】:2015-05-13 09:59:45
【问题描述】:

我正在使用这样的睡眠来每 1/25 秒抓取一帧。操作系统是 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 中做到这一点?我需要它尽可能精确以防止漂移。

谢谢。

【问题讨论】:

  • 也许我没有正确理解这一点,但你不能只做 sleep(.04) 吗?
  • 您还应该知道,您的代码不会真正每 0.04 秒 准确 进行一次循环。诸如sprintfprintf 之类的事情以及您对数据执行的任何其他操作都需要时间。
  • Windows/Linux/您使用的任何桌面操作系统都不是 RTOS。因此,无法保证任何时间。
  • @abuv 如果他使用 usecTosleep,他总是可以通过更改 const 来获得正确的帧速率
  • 你很可能会遇到这个问题(跳帧等)。您可能需要一个对某些硬件事件(hysnc 或 vsync 或其他)做出反应的驱动程序。

标签: c sleep


【解决方案1】:

你的“录音操作”还需要一些时间……

所以你需要计算应该在帧上花费的时间(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);
}

【讨论】:

  • 感谢您的想法。我认为代码实际上不起作用,因为 currentFrameUsec 和 lastFrameUsec 会很快超出范围。一种方法来clock_gettime 两次并得到我猜的差异。我认为以这种方式衡量它肯定会给我带来更好的结果。
【解决方案2】:

在回答您的第一个问题时,没有这样的保证。 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.

【讨论】:

    猜你喜欢
    • 2018-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 1970-01-01
    相关资源
    最近更新 更多