Asio连接池

#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();
    }

}