是否支持在同一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
相关产品推荐
相关产品推荐

