如何从阻塞呼叫返回?
答
不,这是不可能的。如果你想知道是否有数据需要读取,可以使用select()系统调用 - 如果你只在有数据等待的时候读取,你永远不会阻止
答
也许尝试istream::readsome()
方法。它不会等待设备,只会读取缓冲流缓冲区中的内容。
+0
没有任何流功能等待设备。尽管如此,所有的底层库都可以。 readsome()不会解决问题。 – 2010-01-15 17:48:07
答
既然有人说这是不可能的,我认为它应该是伟大的,但给一些替代品。
我通常会做一些服务器代码,而且我们遇到同步调用(阻塞)到数据库的问题。有时(无论出于何种原因),通话可能不会很快返回,并且您的处理时间有限。
我们采取的解决方案是相当简单的,涉及当然MT:
- 在查询的接收,启动一个定时器,它会调用回调在完成
- 如果成功完成,停用定时器,现在不需要了。
- 做你的处理,并在每个“阻止”的呼叫检查计时器(也在其他定期的间隔会很好):如果它被解雇,你已经太长了,应该放弃处理,并全部赶回去。另一个线程现在负责回答查询,因为你太长了。
- 当计时器触发时,用回调启动一个新的线程,该方法应该以“尽力而为”的方式回答,并且应该避免使用阻塞的呼叫。它可以使用由其它线程使用的BOM,如果所述BOM正确处理MT(锁定和例如)
作为习惯问题,我们设置定时器以一舒适区75%和95%之间允许处理请求的最长时间(由请求类别配置)。
这可以让你整齐地避免阻塞呼叫。如果你不想正确地同步你的BOM(因为它涉及开销),那么“尽力而为”的答案可能是一个简单的重试消息(这是95%)。如果您有清理操作或其他方式(缓存?)来回答,则至少需要在部分BOM中进行同步(即75%)。
select()不幸的是不是标准C++的一部分,并且不能在C++流对象上工作 – 2010-01-15 17:14:02
所有更多不使用C++流对象的理由。 – 2010-01-15 17:15:20
所有更多的理由不使用C++ :) – 2010-01-15 17:45:50