这是我的代码:
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来使用相同的strand_对象包装谓词/条件处理程序;如果是这样,为什么,如果没有,请解释。
答案 0 :(得分: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(); ----------------------------------------------'
}