C ++:如何异步调用同步库调用?(C++: How to call a synchronous library call asynchronously?)

我正在使用一个具有阻塞调用的库,如果它不成功,它永远不会超时。 我希望能够更优雅地处理这种错误情况。 我知道必须有一种方法将调用包装在一个工作线程(或其他类型的委托对象)中,等待x秒,然后如果超过x秒,则抛出异常。 我只需要为库中的一个函数执行此操作。 我该如何实现呢? 我在整个网络上看到了类似的例子,但没有一个正在做我正在尝试做的事情。 谢谢!

I am working with a library that has a blocking call that never times out if it does not succeed. I would like to be able to handle this error condition more gracefully. I know there must be a way to wrap the call in a worker thread (or some other type of delegate object), wait x amount of seconds, and then throw an exception if x amount of seconds have passed. I only need to do this for one function in the library. How do I go about implementing this? I see similar examples all over the net but none that are doing exactly what I'm trying to do. Thanks!



当然,你可能会发现一些看似在你的特定情况下工作的黑客。 但这里的竞争条件很难解决。


但是......如果超时在A阻塞呼叫返回的同时到期怎么办? 具体来说,如果B 认为是时候杀死A ,那么你的OS调度程序决定运行A一段时间,然后你的操作系统决定运行杀死A的B代码?

一句话:你最终会在执行中的某个不确定点杀死A (例如,它可能只是从储蓄账户中扣除了500美元,但尚未向支票账户增加500美元。可能性无穷无尽......)

好的,所以你可以让线程A存在,仅用于运行库调用,然后在完成时发出条件或其他信号。 至少可以原则上使这项工作成为可能。 但即便如此,如果图书馆本身有一些处于不一致状态的内部状态应该如何在不合时宜的时刻被杀?

有很好的理由从C ++ 11标准中省略了异步线程取消。 拒绝吧。 修复库例程。 无论成本如何,从长远来看,几乎肯定比你尝试的更便宜。

My answer is "do not attempt to do this".

Sure, you can probably find some hack that will appear to work in your particular case. But the race conditions here are very hard to fix.

The obvious approach is to have thread A make the blocking call, then set up thread B to kill A if a timeout expires.

But... What if the timeout expires at the same time A is returning from the blocking call? Specifically, what if B thinks it is time to kill A, then your OS scheduler decides to run A for a while, then your OS decides to run the B code that kills A?

Bottom line: You wind up killing A at some indeterminate point in its execution. (For example, maybe it just deducted $500 from the savings account but has not yet added $500 to the checking account. The possibilities are endless...)

OK, so you can have thread A exist for the sole purpose of running the library call, and then signal a condition or whatever when it finishes. At least it is possible to make this work in principle. But even then, what if the library itself has some internal state that gets left in an inconsistent state should A get killed at an inopportune moment?

There are good reasons asynchronous thread cancellation was omitted from the C++11 standard. Just say no. Fix the library routine. Whatever that costs, it is almost certainly cheaper in the long run than what you are attempting.