阻止呼叫后立即调用方法

时间:2012-06-22 20:34:47

标签: c++ multithreading boost boost-thread

我正在使用具有阻止功能的第三方库,也就是说,在完成之前它不会返回;我可以为该通话设置超时时间。

问题是,该函数将库置于某种状态。一旦进入该状态,我需要从我自己的代码中做一些事情。我的第一个解决方案是在一个单独的线程中执行此操作:

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,并在进行调用后工作之前设置足够高的延迟以确保调用库函数。它不是确定性的,但大部分时间都有效。

2 个答案:

答案 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)

我理解的问题是你需要这样做:

  1. 输入阻止电话
  2. 在您输入阻止通话后但在完成之前,您需要执行其他操作
  3. 您需要在阻止呼叫返回
  4. 之前完成#2

    从纯粹的C ++角度来看,你无法以确定的方式接受这一点。这是在不了解您正在使用的库的详细信息。

    但我注意到你的超时值。这可能会提供一个漏洞,也许。

    如果您:

    怎么办?
    1. 输入超时为零的阻止呼叫,以便立即返回
    2. 你是其他的东西,无论是在同一个线程中还是与主线程同步。也许使用屏障。
    3. 验证完成#2后,再次输入阻止呼叫,正常非零超时。
    4. 只有在输入阻塞调用且超时为零的情况下,库的状态才会发生变化,这只会起作用。