io_serviceのio.run()
メソッドを呼び出したスレッドの1つが補完ハンドラを呼び出すことは明白です。しかし、私には分かりませんが、読み込み/書き込みの非同期メソッドがどのスレッドで行われるかが分かりません。それはメソッドと呼ばれるスレッドですか、それともio.run()
メソッドを呼び出したスレッドの1つですか?あるいは、最後に、ライブラリーは裏で別のスレッドを作成して操作を実行しますか?どのスレッド非同期操作が発生するか
答えて
例えば、リモートパートナーに非同期のデータを送信したいとします。
boost::asio::async_write(_socket, boost::asio::buffer(msg.data(), msg.size()),
std::bind(&Socket::WriteHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
//Where 'this' is the class Socket
これまでは、ioService.run()
と呼ばれるスレッドを作成していました。 async_write
関数は、ソケットの作成に使用したのと同じものを使用します。ioService
それはあなたのioService
のキューに書き込み操作を実行し、が示すように、ioService
が実行されているスレッドで、ハンドラを実行します。
それは私が疑っていたものです。しかし、私はブーストのドキュメンテーションでこれを明示的に見たことがないので、私は前提をしたくありませんでした。 –
async_*
機能の開始中にI/O操作が試行されます。操作の完了条件が満たされるかエラーが発生すると、操作は完了し、完了ハンドラはio_service
にポストされます。それ以外の場合、操作は完了せず、io_service
の関数poll()
、poll_one()
、run()
、またはrun_one()
を実行しているアプリケーションスレッドが基になるI/O操作を実行するio_service
にエンキューされます。どちらの場合も、完了ハンドラはio_service
を処理するスレッドによって呼び出されます。
を関係なく、非同期操作がすぐにか完了したかどうかの、ハンドラはこの関数内から呼び出されることはありません。
async_write()
ドキュメントが非同期操作がすぐに完了することができることを指摘しています。ハンドラの呼び出しは、boost::asio::io_service::post()
を使用するのと同じ方法で実行されます。
も、この動作がRequirements on Asynchronous Operationsドキュメントに記載されています
- バウンドの構築:非同期操作が完了すると
、操作のためのハンドラが呼び出されますでいるかのようハンドラの完了ハンドラ
bch
- 遅延呼び出しのハンドラをスケジュールするために
ios.post(bch)
を呼び出すには...
これは、非同期操作が直ちに完了した場合でも、開始関数内からハンドラを直接呼び出さないことを意味します。ここで
この動作完全な例demonstratingです。その中にはsocket1
とsocket2
が接続されています。最初はsocket2
にはデータがありません。しかし、socket2
はio_service
が実行されていなくてもデータを持っている、async_write(socket1, ...)
を呼び出した後:あなたはそれのブロック何らかの操作かどうかを知りたいので、またはあなたは、スレッドがローカル状態かを知りたいので、
#include <boost/asio.hpp>
constexpr auto noop = [](auto&& ...){};
int main()
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
// Create all I/O objects.
tcp::acceptor acceptor{io_service, {{}, 0}};
tcp::socket socket1{io_service};
tcp::socket socket2{io_service};
// Connect sockets.
acceptor.async_accept(socket1, noop);
socket2.async_connect(acceptor.local_endpoint(), noop);
io_service.run();
io_service.reset();
// Verify socket2 has no data.
assert(0 == socket2.available());
// Initiate an asynchronous write. However, do not run
// the `io_service`.
std::string data{"example"};
async_write(socket1, boost::asio::buffer(data), noop);
// Verify socket2 has data.
assert(0 < socket2.available());
}
- 1. 非同期操作内の非同期操作
- 2. 非同期操作と非同期ネットワークタスク?
- 3. 非同期操作
- 4. ユニットテストの非同期操作
- 5. 非同期操作のループ
- 6. WCF非同期操作+ IO操作
- 7. ORMLite非同期操作
- 8. JestJSで同期コードをテストすると非同期動作が発生する
- 9. React:shouldComponentUpdateが非同期操作を待つ
- 10. 非同期スレッド
- 11. コールバックすべての非同期操作
- 12. I/Oバウンド操作とCPU負荷操作のJavaスレッド同期
- 13. 現在のスレッドをブロックする非同期操作を強制します
- 14. 非同期操作が同期して完了したら?
- 15. WCF非同期のみの操作
- 16. は、DOM操作(jQueryなど)を非同期ですか?
- 17. グローバルリクエストフィルタ非同期操作の順序
- 18. 非同期操作の実行方法
- 19. redisメッセージの非同期操作
- 20. C++でのWinRT非同期ファイル操作
- 21. WCFclient操作のみ非同期ネットコア2.0
- 22. レルム-Xamarinでの非同期操作
- 23. ASP.Netカスタムハンドラーの非同期操作
- 24. Actionscriptでの非同期操作
- 25. 非同期データベース挿入操作のシーケンシャルID生成
- 26. 非同期操作 - 操作が長時間実行されているかどうかを確認する
- 27. C#.NETでは、非同期操作では必然的にブロックするスレッドが作成されますか?
- 28. Java NIOノンブロッキングモードとnode.js非同期操作
- 29. Apache Camel:非同期操作とバックプレッシャー
- 30. ASP.NET CORE非同期操作ユーザーアラート
このです変数は、または他の目的ですか? – Yakk
私はクリティカルなアプリケーションを開発しており、アプリケーションが実行しているスレッドに時間を費やすことはできません。 run()メソッドを呼び出したスレッドの1つで操作を書き込むために、lambda do io_serviceをポストすることができます。ただし、ライブラリ自体が書き込み操作を実行するスレッドを別のスレッドに作成する場合は、io_serviceに投稿する必要はありません。 –
[Platform-Specific Implementation Notes](http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/overview/implementation.html)のドキュメントには、すべての内部スレッドの作成と目的が記載されています。いずれの内部スレッドも書き込み操作を処理しません。 –