如何从被阻止的呼叫中返回?

发布于 2024-08-18 08:53:30 字数 105 浏览 8 评论 0原文

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

int x;
std::cin >> x;

例如...

is it possible to force a thread to return from a call to a blocking function such as a blocking read from a stream ?

int x;
std::cin >> x;

for example...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

后eg是否自 2024-08-25 08:53:30

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

No, it's not possible. If you want to find out whether there's data to read, use the select() syscall - if you only read when there's data waiting, you'll never block

枕花眠 2024-08-25 08:53:30

您可以查看 istream 对象。

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

You can peek an istream object.

Another method is to have a separate thread permanently waiting on console input and placing the data in a queue or buffer. The interface to the buffer is then up to you, you can make it blocking, non-blocking, or timeout (or all three).

旧时模样 2024-08-25 08:53:30

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

我通常会做一些服务器代码,并且我们在对数据库的同步调用(被阻止)方面遇到同样的问题。有时(无论出于何种原因)呼叫可能返回得不够快,并且您的处理时间有限。

我们采用的解决方案非常简单,当然涉及到 MT:

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

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

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

Since it's been said it is not possible, I think it should be great though to give some alternatives.

I usually do some server code and we have the same problem with synchronous calls (blocked) to the database. Sometimes (for whatever reason) the call may not return quickly enough, and you have a limited time for the processing.

The solution we have adopted is pretty simple, and involves MT of course:

  • Upon reception of the query, start a timer which will call a callback at completion
  • If you complete successfully, deactivate the timer, it is not needed now.
  • Do your processing, and after each "blocked" call check the timer (also at other regular intervals would be great): if it's been fired, you have been too long and should abandon the processing and return with all haste. Another thread is now in charge to answer the query since you've been too long.
  • When the timer fires, start a new thread with the callback, this method is supposed to answer in a "best effort" manner and should refrain from using blocked calls. It may use the BOM used by the other thread if the said BOM handles MT correctly (locking and such)

As a matter of habit, we set the timer to a confortable zone between 75% and 95% of the maximum time allowed to process a request (configured by category of requests).

This allows you to neatly avoid the blocking calls. If you don't want to properly synchronize your BOM (since it involves overhead), the "best effort" answer could well be a simple retry message (that's the 95%). If you have cleanup to do or another way (cache?) to answer, you'll need synchronization in part of the BOM at least (that's the 75%).

情深已缘浅 2024-08-25 08:53:30

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

Maybe try the istream::readsome() method. It doesn't wait for the device and only reads what's in the buffer of a buffered stream.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文