0

私のアプリ(C ++、Windows)は外部デバイスと通信しています。一定時間応答しない場合は、ステータス変数をリセットしたいと思います。

私の最初のアプローチは

auto timer = boost::asio::deadline_timer(io_svc);

timer.expires_from_now(boost::posix_time::seconds(10));
timer.async_wait(boost::bind(&Class::CurrRequestTimeout, this, boost::asio::placeholders::error));

io_svc.poll();

とタイムアウト機能

void Class::CurrRequestTimeout(const boost::system::error_code & ec)
{
    if (ec)
    {
        // this timeout was canceled
        return;
    }
    ResetStatusVariable();
}

これは非ブロッキングである必要があります。そのため、run()ではなくpoll()を選択しました(ここを参照)。ただし、poll()を使用すると、timeoutメソッドが呼び出されることはありません。run()を使用すると問題なく動作しますが、これにより実行がブロックされます。

4

2 に答える 2

2

このpoll関数は、その瞬間に実行する準備ができているハンドラーのみを実行します。タイマーはまだタイムアウトしていないため、現在そのハンドラーを実行できません。そして、あなたはそれをブロックしないように頼みました。それで、あなたはそれが何をすることを期待しますか?

コードがスレッドセーフである場合は、でブロックできる別のスレッドを作成しますrun。そうでない場合は、このスレッドに戻ってpoll後で呼び出し、ハンドラーに実行の機会を与える必要があります。

注意点:1つ以上のrunスレッドを作成する場合は、待機するイベントが常に少なくとも1つあることを確認する必要があります。そうしないと、スレッドはハンドラーを待機できなくなります。boost::asio::io_service::workこの目的のためだけにあります。この質問を参照してください。

于 2012-11-26T10:17:06.167 に答える
0

タイムアウトの前に poll を呼び出すと、io_service ポーリングが何もアクションなしで返されるため、(まだ) 何もする必要はありません。タイムアウトまたは外部デバイスからの通信を待っている間に何をしたいですか? ループを実行して、外部デバイスの通信を待機し、io_service をポーリングし、タイムアウト フラグをチェックすることができます。

while (!checkForExternalDevicesCommunication())
{
  io_svc.poll();
  if (statusVariableHasTimeout())
    throw CommunicationTimeoutException();

  doSomethingInTheMeanTime();
  std::this_thread::sleep(some_time);
}

または、Boost.Asio スタイルの非同期方式で外部デバイスとの通信を実装し、同じ io_service で実行できるようにします。

于 2012-11-26T10:26:30.643 に答える