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

如何将对象的所有异步操作纳入boost::asio::strand?两种方案可行吗?

Boost.Asio strand 方案有效性分析

背景

官方Boost.Asio教程中展示了用boost::asio::bind_executor函数返回新处理器,自动通过strand对象调度完成处理器的用法,示例代码如下:

#include <boost/asio.hpp>
#include <iostream>
#include <thread>

class Printer1
{
public:
Printer1(boost::asio::io_context& io)
: m_strand{boost::asio::make_strand(io)}
, m_timer1{io}
, m_timer2{io}
{
    m_timer1.async_wait(boost::asio::bind_executor(m_strand, [this](const boost::system::error_code& error){std::cout << "1 ";}));
    m_timer2.async_wait(boost::asio::bind_executor(m_strand, [this](const boost::system::error_code& error){std::cout << "2 ";}));
}
private:
    boost::asio::strand<boost::asio::io_context::executor_type> m_strand;
    boost::asio::steady_timer m_timer1;
    boost::asio::steady_timer m_timer2;
};

现在需要验证:以下两种实现方案能否将定时器的所有操作都放入同一个strand中?


方案一(Printer2)

代码实现

class Printer2
{
public:
Printer2(boost::asio::io_context& io)
: m_strand{boost::asio::make_strand(io)}
, m_timer1{m_strand}
, m_timer2{m_strand}
{
    m_timer1.async_wait([this](const boost::system::error_code& error){std::cout << "1 ";});
    m_timer1.async_wait([this](const boost::system::error_code& error){std::cout << "2 ";});
}
private:
    boost::asio::strand<boost::asio::io_context::executor_type> m_strand;
    boost::asio::steady_timer m_timer1;
    boost::asio::steady_timer m_timer2;
};

有效性分析

可以达到目标。当用strand对象初始化steady_timer时,定时器会将strand作为自己的默认执行器。后续调用async_wait时,如果没有显式指定其他执行器,定时器会自动使用这个strand来调度完成处理器。因此,所有定时器的异步操作完成后,对应的回调都会在同一个strand中串行执行,保证线程安全。


方案二(Printer3)

代码实现

class Printer3
{
public:
template <typename Executor>
Printer3(Executor executor)
: m_timer1{executor}
, m_timer2{executor}
{
    m_timer1.async_wait([this](const boost::system::error_code& error){std::cout << "1 ";});
    m_timer1.async_wait([this](const boost::system::error_code& error){std::cout << "2 ";});
}
private:
    boost::asio::steady_timer m_timer1;
    boost::asio::steady_timer m_timer2;
};

int main()
{
    boost::asio::io_context io;
    Printer3 p{boost::asio::make_strand(io)};
    // ...
}

有效性分析

同样可以达到目标。这里通过模板构造函数接收一个strand执行器,并用它初始化两个定时器。和方案一原理一致,定时器的默认执行器被设置为传入的strand,后续async_wait的回调会自动通过该strand串行调度。这种写法更灵活,允许调用者决定使用哪种执行器(strand或直接用io_context),但在当前场景下,传入strand后就能保证所有定时器操作都在同一个strand中执行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:08:17