自制超时的最佳做法

Best practice for self made timeout

本文关键字:最佳 超时      更新时间:2023-10-16

我正在尝试在执行一些轮询的C++方法中实现超时。该方法当前如下所示(无超时):

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

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

  • 应该在系统时间的变化中幸存下来
  • 超时(以毫秒为单位)(一些抖动是可以接受的)
  • 兼容 POSIX
  • 不应使用信号(是库的一部分,避免副作用)
  • 可能使用加速

我目前正在考虑使用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());

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

对于此类问题,什么被认为是最佳实践?

提前感谢!

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

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

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

如果你想便携,clock不是正确的选择。在符合标准的系统上,这是您的进程使用的 CPU 时间,在 Windows 上,它似乎是挂钟时间。此外,usleep在当前的POSIX中已经过时,您应该使用nanosleep

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

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