You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在组合函数中使用boost::asio::defer()?Boost 1.66用法疑问

关于Boost.Asio中defer替代asio_handler_is_continuation的正确用法

嘿,我来帮你理清这个问题~从Boost 1.66开始弃用asio_handler_is_continuation钩子,转而用defer,本质是把原来隐式的钩子判断改成了显式调用,逻辑其实更清晰。

核心逻辑对应

原来你通过重载asio_handler_is_continuation并返回true,是在告诉Asio:“这个handler是前一个异步操作的延续,不需要额外调度,直接在当前完成处理的线程里执行就行”。而defer就是干这个事的——当你用defer提交任务时,Asio的行为就和钩子返回true时的post完全一致。

具体用法示例(结合async_read_until场景)

假设之前你用钩子的写法是这样的:

// 旧写法:依赖asio_handler_is_continuation钩子
void on_read_complete(const boost::system::error_code& ec, std::size_t bytes_read) {
    if (!ec) {
        // 先处理读取到的数据...
        // 发起下一次读取,希望作为延续操作执行
        boost::asio::async_read_until(m_stream, m_buffer, '\n', std::bind(&MyClass::on_next_read, this, std::placeholders::_1, std::placeholders::_2));
    }
}

// 重载钩子函数,标记我们的handler为延续
template <typename Handler>
bool asio_handler_is_continuation(Handler* handler) {
    // 这里需要判断handler是否是我们的目标handler,返回true
    return /* 你的判断逻辑 */;
}

现在改成defer的写法,直接显式声明延续操作:

// 新写法:用defer替代钩子
void on_read_complete(const boost::system::error_code& ec, std::size_t bytes_read) {
    if (!ec) {
        // 先处理读取到的数据...
        // 用defer提交下一次读取的发起操作,Asio会直接在当前线程执行
        boost::asio::defer(m_stream.get_executor(), [this]() {
            boost::asio::async_read_until(m_stream, m_buffer, '\n', [this](const boost::system::error_code& ec2, std::size_t bytes2) {
                on_next_read(ec2, bytes2);
            });
        });
    }
}

关键区别和注意点

  • 显式 vs 隐式:原来的钩子是全局重载,需要识别特定的Handler类型,很容易出错;defer是在需要的地方直接调用,语义更明确,可读性更强。
  • 执行时机:defer提交的任务会被放到当前调用链的末尾执行,不会触发额外的线程切换,和钩子返回true时的post行为完全一致。
  • 适用场景:当你在一个异步操作的完成handler里,紧接着发起另一个相关的异步操作,并且希望避免不必要的线程调度开销时,就用defer。

内容的提问来源于stack exchange,提问作者he rambled

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:05:45