1

誰かがどのような条件下でboost::asioio_service::run()メソッドが返されるか教えてもらえますか?のドキュメントドキュメントは、io_service::run()実行する作業またはディスパッチするハンドラーがある限り、run()戻らないことを示唆しているようです。

私がこれを求めている理由は、サーバーに接続してhttpPOSTを実行するレガシーhttpsクライアントがあるためです。クライアントの関心の分離は、私たちが望んでいるものとは少し異なるため、いくつかの変更を加えていますが、問題が発生しています。

現在、クライアントには基本的にconnect()、サーバーとのプロトコル会話全体を効果的に駆動する誤った名前の呼び出しがあります。呼び出しは、オブジェクトをconnect()作成して呼び出すことから始まります。これにより、 asioコールバック内から新しい呼び出しが行われるチェーンが開始されます。boost::asio::ip::tcp::resolver::async_resolve()asio

void connect()
{
    m_resolver.async_resolve( query, bind( &clientclass::resolve_callback, this ) );
    thread = new boost::thread( bind( &boost::asio::io_service::run, m_io_service ) );
}
void resolve_callback( error_code & e, resolver::iterator i )
{
    if (!e)
    { 
        tcp::endpoint = *i;
        m_socket.lowest_layer().async_connect(endpoint, bind(&clientclass::connect_callback,this,_1,++i));
    }
}
void connect_callback( error_code & e, resolve::iterator i )
{
    if (!e)
    { 
        m_socket.lowest_layer().async_handshake(boost::asio::ssl::stream_base::client,
            bind(&clientclass::handshake_callback,this,_1,++i));
    }
}
void handshake_callback( error_code &e )
{
    if (!e)
    {
        mesg = format_hello_message();
        http_send( mesg, bind(&clientlass::hello_resp_handler,this,_1,_2) );
    }
}
void http_send( stringstream & mesg, reply_handler handler )
{
    async_write(m_socket, m_request_buffer, bind(&clientclass::write_complete_callback,this,_1,handler));
}
void write_comlete_callback( error_code &e, reply_handler handler )
{
    if (!e)
    {
        async_read_until(m_socket,m_reply_buffer,"\r\n\r\n", bind(&clientclass::handle_reply,this,handler));
    }
}
...

とにかく、これはプロトコルの会話が完了するまでプロトコルを介して続行されます。ここのコードからconnect()、メインスレッドで実行されている間、後続のすべてのコールバックとリクエストがで作成されたワーカースレッドに戻ってくることがわかりますconnect()。これは「機能する」コードです。

このチェーンを分割して外部インターフェイスを介して公開しようとすると、機能しなくなります。特に、オブジェクトhandle_handshake()の外部で呼び出しを行っていclientclassます。次にhttp_send()、はインターフェイスの一部であり(または外部インターフェイスによって呼び出され)、io_service :: run()を呼び出すための新しいワーカースレッドを作成します。async_write()呼び出されても、返されていない場合でもwrite_complete_callback()、io_service :: run()が終了します。エラーなしで終了し、ハンドラーがディスパッチされなかったと主張しますが、まだ「作業」を行う必要がありますか?

それで、私が疑問に思っているのはio_service::run()、「仕事」の定義は何ですか?保留中のリクエストですか?既存のコードのこの要求と応答のチェーン中に決して戻らないのはなぜですか?io_service::run()しかし、スレッドを再起動して新しいチェーンを開始しようとすると、作業が完了する直前に返されますか?

4

1 に答える 1

3

呼び出しのコンテキストでの作業の定義は、run()その io_service オブジェクトに対する保留中の非同期操作です。これには、操作に応じたハンドラーの呼び出しが含まれます。そのため、ある操作のハンドラーが別の操作を開始した場合、常に使用可能な作業があります。

さらにio_service::work、オブジェクトが破棄されるまで完了しない io_service で作業を作成するために使用できるクラスがあります。

1 つのチェーンが完了すると、io_service はすべての非同期操作を完了し、新しい操作を開始せずにすべてのハンドラーが呼び出されたため、戻ります。を呼び出すまでio_service::reset()、さらに を呼び出すと、run()操作を実行せずに返されます。

于 2012-10-25T00:15:41.523 に答える