增强 ASIO 阻止回调
Boost ASIO blocking callbacks
从asio到阻止的回调是否安全(或合理(?
void Connection::start() {
/* Assume std::string buffer; that has data to write. */
auto callbackFn = boost::bind(&Connection::callback, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred);
boost::asio::async_write(_socket, boost::asio::buffer(buffer), callBackFn);
}
void Connection::callback(const boost::system::error_code& error,
std::size_t bytesSent) {
/* Perform long running action with bytes sent */
boost::asio::async_write(...);
}
还是我应该在回调中生成一个线程,然后在该线程完成后立即返回并执行操作?
是的,这在许多情况下是合理的。但是,作为架构师,您有责任确定它在您的方案中是否真正合理。
一般来说,您的io_service
将在一个线程上运行,这就是它将调用您的回调的线程,这意味着它在调用回调时不会处理消息。如果没关系,那你就可以走了。(请注意,这里出现了"安全"部分 - 您是否正确保护了对象以便跨线程使用?
如果不好,那么您应该将消息发送到另一个线程进行处理。
至于我和我的房子,我们更喜欢活动对象模式,以保持IO服务的响应,并将多线程的担忧降至最低。请参阅 Herb Sutter 关于有效并发的系列文章。具体来说,您应该阅读:
- "正确使用线程 = 隔离 + 异步消息">
- "更喜欢使用活动对象而不是裸线程">
PS,如果可能的话,放弃boost::bind()
,转而使用 C++11/14 lambda。
更新:至于为什么更喜欢lambda,答案归结为清晰度和可维护性(性能大致相同,lambdas略有优势(。一旦你习惯了用于捕获的 lambda 语法和其他什么,它就会更自然。Bind 需要"从内到外"阅读它,在脑海中解析永远不会变得自然,对于成员函数和捕获引用来说甚至更加乏味。考虑(改编自 Boost 文档(:
struct S
{
void foo( int&, double ) const;
} s;
// ...
auto x = 0;
auto binder = bind( &S::foo, s, ref(x), placeholder::_1 ); // s.foo(x-as-ref, _1)
auto lambda = [&]( auto d ) { s.foo( x, d ); };
auto d = 42.0;
binder( d );
lambda( d );
底部的调用语法是相同的,但 lambda 定义对实际发生的事情更加清晰。Lambda 也很容易扩展到多个语句,而 bind 则不会。
相关文章:
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- Boost.Asio:不能使用 std::bind() 来指定回调
- 增强 ASIO 阻止回调
- Boost Asio和Co_await-与任何第三方回调一起使用
- boost::asio::async_read 不会回调我的处理程序函数
- boost asio,async_read和acync_write未调用回调
- ASIO IO完成回调订单与实际IO操作的顺序
- boost::asio,为什么我的socket在调用async_receive_from后立即运行回调函数
- 提升 ASIO,async_read_some未调用回调
- 持续调用 boost::asio::read_async:无数据的回调
- 提升 asio ssl:如果私钥传递上下文::use_private_key,则不调用密码回调
- (如何)当std::future准备就绪时,我可以获得boost::asio::io_service的回调吗
- 虚拟ASIO服务回调
- 提升 asio async_write回调未被调用
- boost::asio async_read 不接收数据或使用回调
- 提升 Asio 回调未被调用
- boost asio何时调用async_read_some回调?
- 使用boost::asio和c++11 lambda的简单回调控制
- 为什么boost asio async_read_some在特定情况下不调用回调