2013-04-08 119 views
0

這裏是我的代碼:正確使用asio :: io_service :: strand?

void client_connection::serve() 
{ 
    asio::async_read(this->socket_, asio::buffer(&buffer_, buffer_.size()), 

     // predicate/condition (do I wrap this?) 
     std::bind(&client_connection::handle_read_predicate, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2), 

     // handler 
     this->strand_.wrap(std::bind(&client_connection::handle_read, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2))); 
} 

std::size_t client_connection::handle_read_predicate(const asio::error_code& error, std::size_t bytes_) 
{ 
    // useless flawed function, for now 

    // std::cout << "test: reached predicate, " << bytes_ << std::endl; 

    return 0; 
} 

void client_connection::handle_read(const asio::error_code& error_, std::size_t bytes_) 
{ 
    // useless flawed function, for now 

    if (error_) return; 

    this->serve(); 
} 

我的問題是,它是否會正確使用ASIO :: io_service對象::鏈包具有相同strand_對象​​謂詞/條件處理程序;如果是這樣,爲什麼,如果不是,請解釋。

回答

3

沒有必要將它包裹在鏈中。

根據strand記錄,對於組成操作,例如async_read自由函數,所有中間處理程序都在處理程序的代碼段中調用。這樣做的一個副作用是CompletionCondition的所有中間調用也是從鏈內調用的。

但是,請確保在啓動異步循環時在鏈中分派client_connection::serve()的初始調用,因爲初始的CompletionCondition和異步讀取套接字操作發生在調用者的上下文中。例如,在下圖中,所有的呼叫,socket.async_read()client_connection::handle_read_predicate()client_connection::handle_read()將在鏈內發生:

void client_connection::start() 
{ 
    strand_.dispatch(std::bind(&client_connection::serve, 
          shared_from_this())) --------. 
}               | 
    .-----------------------------------------------------' 
    | .--------------------------------------------------. 
    V V             | 
void client_connection::serve()       | 
{               | 
    async_read(socket_, buffer,        | 
    std::bind(&client_connection::handle_read_predicate, | 
       this),          | 
    strand_.wrap(          | 
     std::bind(&client_connection::handle_read,   | 
       shared_from_this())); --.     | 
}          |     | 
    .-----------------------------------'     | 
    V              | 
void client_connection::handle_read(...)     | 
{               | 
    if (error) return;          | 
    serve(); ----------------------------------------------' 
} 
+0

所以,如果我理解正確的話,我可以從例如刪除strand_.wrap之上並改變第一strand_.dispatch到strand_.wrap沒有問題? – kvanberendonck 2013-04-08 23:12:44

+1

@kvanberendonck:編號'strand :: wrap()'只創建一個處理程序,提供的處理程序和返回的處理程序都不會被調度或發佈到'io_service'。替換'strand_.dispatch'會導致無操作。 'strand_.dispatch'序列化第一個'socket_.async_read()'和'handle_read_predicate'的執行;而'strand_.wrap()'在'server()' - >'handle_read()'異步鏈中序列化所有其他'socket_.async_read()'調用,'handle_read'和'handle_read_predicate'。有關更多詳細信息,請參閱[this](http://stackoverflow.com/a/12801042/1053968)回答。 – 2013-04-09 12:21:45

相關問題