1

ブロッキング機能を持つサードパーティのライブラリを使用しています。つまり、完了するまで戻りません。その呼び出しのタイムアウトを設定できます。

問題は、その関数がライブラリを特定の状態にすることです。その状態になるとすぐに、自分のコードから何かをする必要があります。私の最初の解決策は、別のスレッドでそれを行うことでした:

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 ミリ秒待つのは保証としては不十分であり、この特定のタスクはできるだけ速く実行する必要があるため、これ以上待つことはできません。

これを行うより良い方法はありませんか?ライブラリのコードにアクセスできないと考えてください。ブースト ソリューションは大歓迎です。

更新: 回答の 1 つが言うように、ライブラリ API は定義されていません。問題を説明し、解決策を提案する電子メールを開発者に送信しました (つまり、非ブロッキング呼び出しを行い、状態の変化を通知する登録済みのコールバックにイベントを送信します)。それまでの間、タイムアウトを十分に高く設定して X の処理を​​確実に完了させ、呼び出し後の作業を実行する前にライブラリ関数が確実に呼び出されるように遅延を十分に高く設定しました。決定論的ではありませんが、ほとんどの場合は機能します。

4

2 に答える 2

2

私が理解している問題は、これを行う必要があるということです:

  1. ブロッキングコールを入力してください
  2. ブロッキングコールに入った後、完了する前に、何か他のことをする必要があります
  3. ブロッキング呼び出しが戻る前に #2 を終了する必要があります

純粋に C++ の観点からは、決定論的な方法でこれを実現する方法はありません。それは、使用しているライブラリの詳細を理解していないことです。

しかし、タイムアウト値に気付きました。それは抜け穴を提供するかもしれません、多分。

次の場合:

  1. タイムアウトゼロでブロッキング呼び出しに入り、すぐに戻るようにします
  2. 同じスレッドで、またはメインスレッドと同期して、他のことを行います。バリアを使っているのかもしれません。
  3. #2 が完了したことが確認されたら、通常のゼロ以外のタイムアウトで、ブロッキング コールを再度入力します。

これは、タイムアウトなしでブロッキング呼び出しに入った場合にライブラリの状態が変化する場合にのみ機能します。

于 2012-06-22T21:04:39.380 に答える
2

ブーストフューチャーを使用すると、このコードが明確になりますか? ブーストの将来のドキュメントの例を使用するには:

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

関数呼び出しが発生したことを確認するために、おそらく少しの遅延が必要になると思われますが(この問題のこのビットはかなり不明確に思われます-ポストを安全に実行できるときに決定論的に確立できる方法はありますか-状態変更を呼び出しますか?)。

于 2012-06-22T20:42:12.443 に答える