这是睡眠()的正确用法吗?

时间:2015-05-13 09:59:45

标签: c sleep

我正在使用这样的睡眠来每隔1/25秒抓一个框架。操作系统是Debian 6 armel。

$check = $db->lastInsertId() or
$check = $db->fetch(PDO::FETCH_ASSOC) or
$check = $db->fetchAll(PDO::FETCH_ASSOC)

问题:循环每隔1/25秒将缓冲区输出到输出文件描述符的保证是什么?
在C中有更好的方法吗?我需要尽可能精确地防止漂移。

谢谢。

2 个答案:

答案 0 :(得分:2)

您的“录制操作”仍需要一段时间......

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

答案 1 :(得分: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.