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

是否支持在同一strand上执行boost::asio::~strand<>析构函数?

问题:是否支持在同一strand上执行boost::asio::~strand<>?

查阅到的文档矛盾

已废弃的boost::asio::io_context::strand::~strand文档有明确说明:

通过strand提交但尚未被调用的处理程序仍会以满足非并发保证的方式被调度。

而当前版本的boost::asio::strand::~strand文档无此描述,但两种strand的核心实现逻辑一致,废弃版本的文档暗示该场景是安全的。

背景场景

按照Boost.Asio文档推荐的方式,用shared_from_this管理TCP会话生命周期时,会话自身代码会销毁最后一个std::shared_ptr,触发~session。当会话持有显式boost::asio::strand作为执行器时,~session会在当前strand上下文中执行~strand,因此产生是否存在隐患的疑问。

示例代码

#include <iostream>
#include <memory>

#include <boost/asio.hpp>

//更具体的场景可以是TCP会话
struct session : std::enable_shared_from_this<session> {
    session (boost::asio::io_context& context) : strand(boost::asio::make_strand(context)), timer(context){}
    void start() {
        boost::asio::co_spawn(strand, loop(shared_from_this()), boost::asio::detached);
    }

    //假设从另一个协程调用,如TCP连接EOF时
    void stop () {
        boost::asio::post(boost::asio::bind_executor(strand, [me = shared_from_this()] () {
            me->timer.cancel();
        }));
    }

private:
    boost::asio::strand<boost::asio::io_context::executor_type> strand;
    boost::asio::steady_timer timer;

    boost::asio::awaitable<void> loop(std::shared_ptr<session> self) {
        while (true)  {
            timer.expires_from_now(std::chrono::seconds{5});
            co_await timer.async_wait(boost::asio::use_awaitable);
            std::cout << "5 seconds expired" << std::endl;
            self->stop();
        }
    } //触发~session,进而析构strand,是否有隐患?是否属于未定义行为?
};


int main(int argc, char* argv[]) {
    boost::asio::io_context context;
    {
        auto s = std::make_shared<session>(context);
        s->start();
    }
    while (true) {
        try {
            context.run();
            break;
        } catch (std::exception const& e) {
            std::cerr << "Exception in context::run(): " << e.what() << std::endl;
        }
    }
}

结论

这种场景安全且被支持,不属于未定义行为,原因如下:

  • strand的非并发保证确保同一时刻只有一个处理程序在运行,当在strand上下文执行析构时,strand的任务队列已经为空,不存在待执行任务与析构操作的冲突。
  • 废弃版本的文档描述反映了strand的核心设计意图:即使析构strand,已提交的任务仍会按规则执行;而在strand自身上下文析构时,更不存在资源竞争问题。
  • 从实现逻辑看,strand的内部同步机制会在析构时正确清理资源,不会出现非法访问或未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:30:58