1

是否可以强制线程从对阻塞函数的调用返回,例如从流中阻塞读取?

int x;
std::cin >> x;

例如...

4

4 回答 4

5

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

于 2010-01-15T17:08:30.947 回答
0

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

于 2010-01-15T17:45:33.807 回答
0

您可以查看istream 对象。

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

于 2010-01-15T18:54:22.883 回答
0

既然有人说这是不可能的,我认为提供一些替代方案应该很好。

我通常会做一些服务器代码,我们对数据库的同步调用(阻塞)也有同样的问题。有时(无论出于何种原因)呼叫可能无法足够快地返回,并且您的处理时间有限。

我们采用的解决方案非常简单,当然也涉及到机器翻译:

  • 收到查询后,启动一个计时器,该计时器将在完成时调用回调
  • 如果您成功完成,请停用计时器,现在不需要它。
  • 进行您的处理,并在每次“阻塞”调用后检查计时器(也可以定期检查计时器):如果它被解雇了,那么您已经太久了,应该放弃处理并尽快返回。由于您的时间太长,现在另一个线程负责回答查询。
  • 当计时器触发时,使用回调启动一个新线程,这个方法应该以“尽力而为”的方式回答,并且应该避免使用阻塞的调用。如果所述BOM正确处理MT(锁定等),它可能会使用其他线程使用的BOM

作为一种习惯,我们将计时器设置为一个舒适的区域,介于允许处理请求的最大时间的 75% 到 95% 之间(按请求类别配置)。

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

于 2010-01-15T19:13:58.880 回答