2013-09-21 38 views
1

我正试图在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()); 

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

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

在此先感谢!

+0

当您说“POSIX compatible”时,您的意思是POSIX 1003.1b-1993和POSIX 1003.1i-1995是否带有Realtime Extensions? – WhozCraig

+0

我的意思是它应该在POSIX兼容系统上运行。 – thammi

回答

1

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

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

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

+0

我应该写下“大约毫秒”。有一些抖动对我的应用程序可以。因为超时只能设置完整的秒数。 – thammi

+2

问题在于你的极限是多么“艰难”(比如,大部分残骸会错过最后期限:电影中的字幕几乎没有问题,在目前的检查中,这可能意味着硬件损坏,机器捕捉火)。如果限制是“软”,那么选择似乎是一个合理的解决方案,并且可能有99.99%的延迟时间相当精确(但是它们可能会有相当一段时间的0.01%)。对于需要在不同环境中使用一些'#ifdef'的代码,我并不感到惊讶。 – 6502

+0

我的问题并不是等待,而是跟踪不断调用'do_something()'(等待)花费了多少时间。超时将在多次迭代后达成。 – thammi

1

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

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

一些代码调用select()所有三套空,nfds零和 非NULL超时一个相当简便的方式与亚秒 精度睡觉。