自制超时的最佳做法

时间:2013-09-21 05:31:10

标签: c++ c posix

我正在尝试在C ++方法中实现超时,它执行一些轮询。该方法目前看起来像这样(没有超时):

do {
    do_something();
    usleep(50);
} while(!is_finished());

解决方案应具有以下属性:

  • 应该能够承受系统时间的变化
  • 超时(以毫秒为单位)(可接受一些抖动)
  • POSIX兼容
  • 不应使用信号(是库的一部分,避免副作用)
  • 可能会使用Boost

我目前正在考虑使用clock()并执行以下操作:

start = clock();

do {
    do_something();
    usleep(50); // TODO: do fancy stuff to avoid waiting after the timeout is reached

    if(clock() - start > timeout * CLOCKS_PER_SEC / 1000) break;
} while(!is_finished());

这是一个很好的解决方案吗?我正试图找到最好的解决方案,因为这种任务似乎经常出现。

这种问题的最佳做法是什么?

提前致谢!

2 个答案:

答案 0 :(得分:1)

任何没有专门提供实时支持的操作系统都无法达到精确到毫秒的超时。

如果您的系统负载很重(甚至是暂时的),很可能会让它在几秒钟内无响应。有时标准(非实时)系统会因访问CD-Rom设备等明显愚蠢的原因而变得非常无响应。

Linux有一些实时变化,而对于Windows IIRC,唯一的实时解决方案实际上有一个实时内核,它管理运行Windows系统的硬件基本上在虚拟机中“模拟”。

答案 1 :(得分:1)

如果您想要便携,

clock不是正确的选择。在符合要求的系统上,这是您的过程使用的CPU时间,在Windows上它似乎是挂钟时间。此外,usleep在当前POSIX中已过时,您应该使用nanosleep

有一种方法可以适用于更广泛的平台select。这个调用有第五个参数,让你放置一个超时。你可以(误)使用它,等待你知道永远不会发生的网络事件,然后在一段受控的时间后超时。从linux上的手册:

  

有些代码调用select(),所有三个集都为空,nfds为零,并且a   非NULL超时是一种相当便携的亚秒睡眠方式          精度。