我有一个问题,关于什么在strand中运行,什么不是。我已经阅读了SO的帖子以及strand的文档,但是我想确保我已经正确理解了以下代码。

下面的类是一个tcp客户端,它异步地将内容发送给关心的人。

我还想提到io_service::run已在多个threads上调用。

int main( )
{
    /* Other stuff */
    client.WriteAsync( buffer1 );
    client.WriteAsync( buffer2 );
}


/* TcpClient class */

void TcpClient::WriteAsync( std::shared_ptr<boost::asio::streambuf> buffer )
{
    // 1
    _strand.post( [ this, buffer ]( )
    {
        _outbuffer.push( buffer );
        if ( _outbuffer.size( ) > 1 ) return;
        // 2
        Write( );
    } );
}

void TcpClient::Write( )
{
    // 3
    boost::asio::async_write( _socket,
        *_outbuffer.front( ),
        // 4
        [ this ]( boost::system::error_code const& error,
            size_t const bytesTransferred )
    {
        _outbuffer.pop( );
        if ( error )
        {
            std::cout << "Error writing: " << error.message( ) << std::endl;
        }
        if ( !_outbuffer.empty( ) )
        {
            // 5
            Write( );
        }
    } );
}


1:调用_strand.post,如果当前没有任何运行,则strand将调度传入的处理程序。在这种情况下,传递给该链的lambda将在该链中执行。如果已经完成工作,则处理程序将排队。

2:Write,当从传递给lambdapost中调用时,在strand中运行

3:在async_write中调用strand。如果async_write尚未完成,则strand将不会调度下一个处理程序。

4:async_write完成处理程序未在strand中运行。调用async_write完成处理程序时,strand将弹出其下一个工作单元并进行调度。

5:Writeasync_write完成处理程序中调用,并且不在strand中运行

我想知道我的上述说法是否正确。

最佳答案

1:调用_strand.post,如果当前没有任何运行,则strand将分派传入的处理程序。在这种情况下,传递给链的lambda将在链中执行。如果已经完成工作,则处理程序将排队。


正确。


  2:写,当从lambda内部调用传递到post时,它在链中运行


正确。


  3:在子链中调用async_write。如果async_write尚未完成,则该链将不会调度下一个处理程序。


不正确当传递给链的lambda“返回”时,将运行链工作的下一个排队位。


  4:async_write完成处理程序不在链中运行。


正确


  调用async_write完成处理程序时,该链将弹出队列中的下一个工作单元,并将其分派。


同样,不正确的是,当传递给链的lambda“返回”时,运行链的下一个排队位。


  5:在async_write完成处理程序中调用write,并且未在链中运行


正确。

如果您希望async_write完成处理程序在子程序段中运行(由于对_outbuffer的共享访问,您很可能这样做),则可以使用bind_executor

例如

void TcpClient::Write( )
{
    boost::asio::async_write( _socket,
        *_outbuffer.front( ),
        // here
        boost::asio::bind_executor(_strand, [ this ]( boost::system::error_code const& error, size_t const bytesTransferred )
    {
        _outbuffer.pop( );
        if ( error )
        {
            std::cout << "Error writing: " << error.message( ) << std::endl;
        }
        if ( !_outbuffer.empty( ) )
        {
            // 5
            Write( );
        }
    } ));
}

10-08 12:01