我正在使用具有阻止功能的第三方库,也就是说,在完成之前它不会返回;我可以为该通话设置超时时间。
问题是,该函数将库置于某种状态。一旦进入该状态,我需要从我自己的代码中做一些事情。我的第一个解决方案是在一个单独的线程中执行此操作:
void LibraryWrapper::DoTheMagic(){
//...
boost::thread EnteredFooStateNotifier( &LibraryWrapper::EnterFooState, this );
::LibraryBlockingFunction( timeout_ );
//...
}
void LibraryWrapper::EnterFooState(){
::Sleep( 50 ); //Ensure ::LibraryBlockingFunction is called first
//Do the stuff
}
相当讨厌,不是吗?我必须调用Sleep
因为:: LibraryBlockingFunction必须在我下面的内容之前调用,否则一切都会失败。但等待50毫秒是一个很差的保证,我不能再等了,因为这个特殊的任务需要尽快完成。
有没有更好的方法呢?考虑到我无法访问图书馆的代码。欢迎提升解决方案。
更新:正如其中一个答案所说,库API定义不明确。我向开发人员发送了一封电子邮件,解释了问题并建议了一个解决方案(即使呼叫无阻塞,并向登记的回叫发送事件通知状态变化)。与此同时,我设置了足够高的超时以确保完成X,并在进行调用后工作之前设置足够高的延迟以确保调用库函数。它不是确定性的,但大部分时间都有效。
答案 0 :(得分:2)
使用boost future会澄清这段代码吗?要使用boost future documentation:
中的示例int calculate_the_answer_to_life_the_universe_and_everything()
{
return 42;
}
boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
boost::unique_future<int> fi=pt.get_future();
boost::thread task(boost::move(pt));
// In your example, now would be the time to do the post-call work.
fi.wait(); // wait for it to finish
虽然为了确保你的函数调用已经发生,你仍然可能需要一点延迟(你的问题的这一点看起来很不明确 - 有什么方法你可以确定地确定执行是否安全呼叫后状态变化?)。
答案 1 :(得分:2)
我理解的问题是你需要这样做:
从纯粹的C ++角度来看,你无法以确定的方式接受这一点。这是在不了解您正在使用的库的详细信息。
但我注意到你的超时值。这可能会提供一个漏洞,也许。
如果您:
怎么办?只有在输入阻塞调用且超时为零的情况下,库的状态才会发生变化,这只会起作用。