3

除了睡觉之外,我有一个关于延迟 C++ 程序的替代方法的问题。

我的程序有一部分接收 UDP 数据包并将其发送到控制器。这部分程序必须异步运行。为了减少此提供程序的开销,我决定使用异步 IO 来接收 UDP 数据包,而不是让单独的线程监视套接字。

我按照这个sigaction 的例子来完成这个。我注意到,如果我在这个 sigaction 处于活动状态时尝试使用 usleep,它会在我收到数据包时打破我的睡眠。这是有道理的,因为我假设 sigaction 是由 CPU 上的某种中断触发的,这可能会阻止 CPU 休眠。如果有人对为什么会发生这种情况有很好的解释,我会很想知道。我的问题是有时我必须连续发送几个数据包并且需要确保延迟它们,否则它们会被我的控制器错过。

我通常会使用睡眠来延迟数据包的发送,但现在我不能,因为它被我的 sigaction 破坏了。我曾考虑过使用繁忙的等待,但它可能太不一致了。我也有可能使用一个使用计时器定期清空的数据包队列,但似乎可能有一个更简单的解决方案。

除了睡眠之外,还有其他方法可以延迟数据包的发送吗?有没有办法设置我的异步 IO 使其不会中断睡眠?我会以错误的方式解决这个问题吗?

4

2 回答 2

4

通常在编写异步程序时,您会切换到事件循环样式的编程。任何事件系统都可以让你设置触发回调的计时器,使用那些你可以设置发送流量的时间表等等。此外,您通常使用它们来监视您的套接字,并在有要读取的内容时简单地调用您的回调。虽然对于 UDP 并不重要,但如果您在任何时候处理 TCP,您还希望在准备好写入套接字时使用它们来调用回调,这样您就不会在尝试写出数据时阻塞您的进程.

我个人喜欢http://libevent.org/虽然我也听说过 libev 的好消息。

于 2014-10-02T19:26:18.170 回答
2

这应该澄清一些事情:

来自睡眠手册:

Return Value
Zero if the requested time has elapsed, or the number of seconds left to sleep, if the call was interrupted by a signal handler. 

一种选择是创建循环来检查时间是否已经过去(因为睡眠返回中断时剩余的秒数)。如果不只是执行另一个睡眠等,直到所需时间结束。

于 2014-10-02T19:48:53.007 回答