所以情况就是这样。我有一个C++库,它正在进行一些进程间通信,使用wait()
函数来阻塞和等待传入的消息。难点是我需要定时等待,如果在指定的时间内没有收到消息,它将返回一个状态值。如何在阻塞呼叫周围实现定时等待?
最优雅的解决方案可能是重写库来为其API添加定时等待,但为了这个问题,我认为这是不可行的。 (实际上,这看起来很困难,所以我想知道其他的选项是什么。)
这是我怎么会做这样一个忙等循环,在伪代码:
while(message == false && current_time - start_time < timeout)
{
if (Listener.new_message()) then message = true;
}
我不尽管如此,你还是需要忙于等待处理器周期。而且我也不想仅在循环中添加sleep()
调用以避免处理器负载,因为这意味着响应速度较慢。我想要一些适当的块和中断。如果更好的解决方案涉及线程(这似乎很可能),我们已经使用boost::thread
,所以我宁愿使用它。
我发布这个问题,因为这似乎是一种明确的“最佳实践”正确的答案,因为这是一种很常见的模式。什么是正确的做法?
编辑补充:我的很大一部分关注点在于,程序中的这一点对性能至关重要,并且对于避免竞争条件或内存泄漏至关重要。因此,虽然“使用两个线程和一个计时器”是有益的建议,但我仍然试图找出如何以一种安全和正确的方式实际实现它,并且我可以很容易地看到自己在代码中犯下新手的错误,甚至不知道我做了什么。因此,一些实际的示例代码将非常感谢!另外,我对多线程解决方案有所担忧:如果我使用“在第二个线程中放置阻塞调用并在该线程上执行定时等待”方法,那么第二个线程会发生什么阻止呼叫永不返回?我知道在第一个线程中的等待时间会返回,我会看到没有答案发生并继续进行,但是我是否已经“泄漏”了一个将永远处于阻塞状态的线程?有什么办法可以避免这种情况? (有什么办法可以避免这种情况,避免泄漏第二个线程的内存?)如果阻塞调用没有返回,我需要的完整解决方案需要避免发生泄漏。
谢谢!我想这听起来像我想要的 - 但我没有足够的细节来了解如何去做。特别是,我不知道如何正确设置一个信号来中断阻塞调用并永久停止它,而不是在中断处理程序退出后再回到它。你能否就如何做到这一点添加一些解释? – 2010-11-20 21:03:25
从我的答案中的GNU链接:“为了能够使用闹钟功能来中断可能无限期阻塞的系统调用,使用sigaction注册信号处理程序时不要设置SA_RESTART标志很重要。我会尝试。那么问题是当它的基本操作返回EINTR时,库代码会做什么。如果幸运的话,你正在使用的库会有某种你可以从你的信号处理程序调用的“停止”函数,或者它只会从EINTR上的阻塞调用中返回。如果它更持久并且在EINTR上再次阻止,生活就会更加困难。 – 2010-11-21 16:52:04
好的,这开始有意义 - 我错过了那条线,也没有意识到SA_RESTART存在,或者中断的代码可能发生任何事情,除了它继续停止的地方。感谢您指出了这一点! (我不确定在这种情况下库代码的作用,或者我们可以在多大程度上依赖它,因为它有钩子让人们为不同的通信库添加不同的代码,但我会发现的。) – 2010-11-22 21:43:03