boost::asio中多线程的使用
代码中的注意事项
- 使用boost::asio::io_service::strand _strand保证线程安全
- strand.wrap可以将线程序列化
- 使用std::thread启动第二线程
代码
编译时要链接库:
g++ -std=c++17 -Wall -Wextra -Iinclude -Llib main.cpp -o main -lboost_system -lpthread
#include <iostream>
#include <boost/asio.hpp>
#include <thread>
#include <boost/date_time/posix_time/posix_time.hpp>
/**
* @brief asio使用简单的多线程
*/
class Printer
{
public:
Printer(boost::asio::io_service & io)
: _strand(io), _timer1(io, boost::posix_time::seconds(1)), _timer2(io, boost::posix_time::seconds(1))
{
_timer1.async_wait(_strand.wrap([this](const auto&) {
this->print1();
}));
_timer2.async_wait(_strand.wrap([this](const auto&) {
this->print2();
}));
}
~Printer()
{
std::cout << "Final count is " << _count << std::endl;
}
void print1()
{
if(_count < 10) {
std::cout << "Timer1: " << _count++ << std::endl;
_timer1.expires_at(_timer1.expires_at() + boost::posix_time::seconds(1));
_timer1.async_wait(_strand.wrap([this](const auto&) {
this->print1();
}));
}
}
void print2()
{
if(_count < 10) {
std::cout << "Timer2: " << _count++ << std::endl;
_timer2.expires_at(_timer2.expires_at() + boost::posix_time::seconds(1));
_timer2.async_wait(_strand.wrap([this](const auto&) {
this->print2();
}));
}
}
private:
//strand保证线程安全,将线程序列化,如果只有一个线程,
//那么asio会提供一个默认的全局strand,程序员可以不写
boost::asio::io_service::strand _strand;
boost::asio::deadline_timer _timer1;
boost::asio::deadline_timer _timer2;
int _count = 0;
};
void main()
{
boost::asio::io_service io;
//在Printer类内部完成事件注册
//事件注册要在第二个线程启动之前,不然可能bug
//导致主线程的io.run()不执行
Printer p(io);
//调用第二个线程并行执行io.run()
std::thread thread([&io]() {
io.run();
});
io.run();
thread.join();
}