如何从阻塞呼叫返回?

问题描述:

是否有可能强制线程从调用返回阻塞函数,如阻塞从流中读取?如何从阻塞呼叫返回?

int x; 
std::cin >> x; 

例如...

不,这是不可能的。如果你想知道是否有数据需要读取,可以使用select()系统调用 - 如果你只在有数据等待的时候读取,你永远不会阻止

+0

select()不幸的是不是标准C++的一部分,并且不能在C++流对象上工作 – 2010-01-15 17:14:02

+0

所有更多不使用C++流对象的理由。 – 2010-01-15 17:15:20

+1

所有更多的理由不使用C++ :) – 2010-01-15 17:45:50

也许尝试istream::readsome()方法。它不会等待设备,只会读取缓冲流缓冲区中的内容。

+0

没有任何流功能等待设备。尽管如此,所有的底层库都可以。 readsome()不会解决问题。 – 2010-01-15 17:48:07

您可以将peek作为istream对象。

另一种方法是让单独的线程永久等待控制台输入并将数据放入队列或缓冲区中。缓冲区的接口由您决定,您可以使其成为阻塞,非阻塞或超时(或全部三种)。

既然有人说这是不可能的,我认为它应该是伟大的,但给一些替代品。

我通常会做一些服务器代码,而且我们遇到同步调用(阻塞)到数据库的问题。有时(无论出于何种原因),通话可能不会很快返回,并且您的处理时间有限。

我们采取的解决方案是相当简单的,涉及当然MT:

  • 在查询的接收,启动一个定时器,它会调用回调在完成
  • 如果成功完成,停用定时器,现在不需要了。
  • 做你的处理,并在每个“阻止”的呼叫检查计时器(也在其他定期的间隔会很好):如果它被解雇,你已经太长了,应该放弃处理,并全部赶回去。另一个线程现在负责回答查询,因为你太长了。
  • 当计时器触发时,用回调启动一个新的线程,该方法应该以“尽力而为”的方式回答,并且应该避免使用阻塞的呼叫。它可以使用由其它线程使用的BOM,如果所述BOM正确处理MT(锁定和例如)

作为习惯问题,我们设置定时器以一舒适区75%和95%之间允许处理请求的最长时间(由请求类别配置)。

这可以让你整齐地避免阻塞呼叫。如果你不想正确地同步你的BOM(因为它涉及开销),那么“尽力而为”的答案可能是一个简单的重试消息(这是95%)。如果您有清理操作或其他方式(缓存?)来回答,则至少需要在部分BOM中进行同步(即75%)。