#pragma once
#include "const.h"
#include <boost/asio.hpp>
#include "Singleton.h"
class AsioIOServicePool : public Singleton<AsioIOServicePool>
{
friend class Singleton<AsioIOServicePool>;
public:
using IOService = boost::asio::io_context;
// 如果io_context如果没有绑定任何任务会结束,不会做事件的轮询
using Work = boost::asio::io_context::work;
// 使用work来绑定io_context
using WorkPtr = std::unique_ptr<Work>;
~AsioIOServicePool();
AsioIOServicePool(const AsioIOServicePool&) = delete;
AsioIOServicePool& operator=(const AsioIOServicePool&) = delete;
boost::asio::io_context& GetIOService();
void Stop();
private:
AsioIOServicePool(std::size_t size = std::thread::hardware_concurrency());
std::vector<IOService> _ioServices;
std::vector<WorkPtr> _works;
std::vector<std::thread> _threads;
std::size_t _nextIOService;
};
AsioIOServicePool::AsioIOServicePool(std::size_t size)
:_ioServices(size),_works(size),_nextIOService(0)
{
for (std::size_t i = 0; i < size; i++)
{
_works[i] = std::unique_ptr<Work>(new Work(_ioServices[i]));
}
// 遍历多个ioservice。创建多个线程
for (std::size_t i = 0; i < _ioServices.size(); i++)
{
_threads.emplace_back([this,i]() {
_ioServices[i].run();
});
}
}
AsioIOServicePool::~AsioIOServicePool() {
Stop();// RAII的思想
}
boost::asio::io_context& AsioIOServicePool::GetIOService() {
auto& service = _ioServices[_nextIOService++];
if (_nextIOService == _ioServices.size())
{
_nextIOService = 0;
}
return service;
}
void AsioIOServicePool::Stop() {
for (auto& work : _works)
{
// 先把服务任务停止,那么注册服务的话就会返回一个无效/错误
work->get_io_context().stop();
// reset是将unique_ptr指向的对象被回收,那么Work被回收
work.reset();
}
for (auto& t : _threads)
{
t.join();
}
}