自己翻译的 没有任何参考价值
Timer.5 - Synchronising handlers in multithreaded programs
https://www.boost.org/doc/libs/1_74_0/doc/html/boost_asio/tutorial/tuttimer5.html
Timer.5 - Synchronising handlers in multithreaded programs
这次的教程会演示在一个多线程程序中用strand类模板来同步执行回调函数.
前面的四篇教程中,我们通过使用单线程上的io_context::run()函数,避免了多线程同步的问题.如你所知,asio库保证回调函数都只会在io_context::run()的执行线程上被执行.也就是说,如果我们只在一个线程上执行io_context::run(),那就意味着各个回调函数不可能并行执行.
以单线程方式来入门asio编程是一个不错的选择.但是单线程也有它的的缺点: 它对程序,特别是服务器上的程序存在限制,这些限制包括:
- 存在耗时操作时.系统的实时响应能力差.
- 在多处理器系统上不能扩展.
如果你苦于这些限制的话,通常的解决方式是去搞一池子线程来执行io_context::run().这样就能实现回调函数的并行处理了.然而,这也使得它们能够同时访问线程不安全的共享数据.因此我们需要一种手段来进行同步.
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/bind/bind.hpp>
首先跟之前一样,定义一个printer类.不过这次在原先的基础改成了两个并行的计时器.
class printer
{
public:
构造函数里除了初始化两个boost::asio::steady_timer成员之外,还初始化了一个叫strand_的成员,这是一个boost::asio::strand< boost::asio::io_context::executor_type >类型的对象.
strand类模板是一种executor adapter(可能翻译成执行者适配器?),它能够保证由他经手的回调函数不会同时执行.当然了,不由同一个strand调度的各个回调函数还是可以并行执行的.
printer(boost::asio::io_context& io)
: strand_(boost::asio::make_strand(io)),
timer1_(io, boost::asio::chrono::seconds(1)),
timer2_(io, boost::asio::chrono::seconds(1)),
count_(0)
{
初始化这些异步操作的时候,每一个回调函数都绑到了一个boost::asio::strand< boost::asio::io_context::executor_type >的类对象上.函数boost::asio::bind_executor()返回的是一个新的回调函数, 这个回调函数已经自动由strand负责调度了.这么一来,这两个函数绑到了同一个strand上面,我们就能确保他们不会被同时执行了.
timer1_.async_wait(boost::asio::bind_executor(strand_,
boost::bind(&printer::print1, this)));
timer2_.async_wait(boost::asio::