2

私はかなり単純なboost::asioセットアップを使用しています。ここでは、メインスレッドからio_service.run()を呼び出します。私はtcpリゾルバーを持っており、非同期リゾルブを使用してアドレスを検索します。そのルックアップが失敗すると、非同期コールバック内で例外をスローします。この例外は、run()呼び出しの外部、メイン関数の内部でキャッチします。次に、io_serviceインスタンス(グローバル)でstop()を呼び出します。ただし、main()が戻ると、プログラムはハングします。リゾルバーサービスからは決して来ないexit_event_を待っていることがわかりました。

出口にぶら下がったくありません。私が間違っていることはありますか?もしそうなら、何ですか?私はこれらのことについてオンラインで多くの議論を見つけていません。Windows7/64ビットでboost1.41.0を使用しています。

4

2 に答える 2

1

次に、io_serviceでstop()を呼び出します

停止する必要がある場合は、このトリック(io_serviceドキュメントio_serviceからコピー)を使用してみてください。

boost::asio::io_service io_service;
auto_ptr<boost::asio::io_service::work> work(
    new boost::asio::io_service::work(io_service));
...
work.reset(); // Allow run() to exit. 

理由は単純です(ドキュメントからも) 。toを呼び出すio_service::stop()と、io_service run()呼び出しができるだけ早く戻り、未完了の操作が破棄され、準備ができたハンドラーのディスパッチが許可されなくなります。

したがって、io_service::stop()すべてのハンドラーをディスパッチする必要がある場合は、呼び出しだけでは不十分です。

于 2011-09-08T22:07:07.360 に答える
0

stop()は、io_serviceに停止するように通知するだけです。stop()呼び出しに続いて別のrun()呼び出しを実行すると、元に戻って適切にクリーンアップする必要があります。

ドキュメントには、ハンドラーからの例外のスローについての説明があります。

また、この問題はオブジェクトの存続期間の問題に関連している可能性があると推測しています。たとえば、他の何かがまだ参照している間にioサービスが破棄されます。例と、オブジェクトがまだ存在していることを確認するために共有ポインターがどのように使用されているかを詳しく見てください。

于 2011-09-09T04:07:04.050 に答える