2017-11-13 11 views
1

io_serviceのio.run()メソッドを呼び出したスレッドの1つが補完ハンドラを呼び出すことは明白です。しかし、私には分かりませんが、読み込み/書き込みの非同期メソッドがどのスレッドで行われるかが分かりません。それはメソッドと呼ばれるスレッドですか、それともio.run()メソッドを呼び出したスレッドの1つですか?あるいは、最後に、ライブラリーは裏で別のスレッドを作成して操作を実行しますか?どのスレッド非同期操作が発生するか

+0

このです変数は、または他の目的ですか? – Yakk

+0

私はクリティカルなアプリケーションを開発しており、アプリケーションが実行しているスレッドに時間を費やすことはできません。 run()メソッドを呼び出したスレッドの1つで操作を書き込むために、lambda do io_serviceをポストすることができます。ただし、ライブラリ自体が書き込み操作を実行するスレッドを別のスレッドに作成する場合は、io_serviceに投稿する必要はありません。 –

+0

[Platform-Specific Implementation Notes](http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/overview/implementation.html)のドキュメントには、すべての内部スレッドの作成と目的が記載されています。いずれの内部スレッドも書き込み操作を処理しません。 –

答えて

0

例えば、リモートパートナーに非同期のデータを送信したいとします。

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が実行されているスレッドで、ハンドラを実行します。

+0

それは私が疑っていたものです。しかし、私はブーストのドキュメンテーションでこれを明示的に見たことがないので、私は前提をしたくありませんでした。 –

0

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です。その中にはsocket1socket2が接続されています。最初はsocket2にはデータがありません。しかし、socket2io_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()); 
} 
関連する問題