仿Muduo库实现高并发服务器——LoopThreadPool模块

这个模块需要具备那些基础知识。

线程创建相关操作,锁,条件变量。

设置线程数量:

_thread_count 是线程池中,记录线程数量的成员。

创建线程池:

上图就是线程池的创建,将线程与EventLoop对象 通过数组下标一一对应起来。

EventLoop对象的分配:

服务器是靠轮询的策略,来降低,每个线程的运行压力。

在TcpServer模块中调用,为新的客户端连接分配EventLoop对象:

线程创建与EventLoop对象进行绑定:

1,首先创建线程,进入线程函数,将EventLoop对象进行实例化,然后通过锁和条件变量来控制,先进行加锁,然后在条件变量_cond.notify_all(),这里等待,等待被唤醒,然后解锁。解锁这一步是_cond.notify_all()做的。

2,接着获取线程对应的EventLoop对象,先加锁,在_cond.wait()唤醒,等待的条件变量,这时线程会执行loop.Start()死循环。出了作用域,锁就会被销毁。

这就需要对锁和条件变量进行了解。

LoopThreadPool模块整体代码:

cpp 复制代码
class LoopThread {
    private:
        /*用于实现_loop获取的同步关系,避免线程创建了,但是_loop还没有实例化之前去获取_loop*/
        std::mutex _mutex;          // 互斥锁
        std::condition_variable _cond;   // 条件变量
        EventLoop *_loop;       // EventLoop指针变量,这个对象需要在线程内实例化
        std::thread _thread;    // EventLoop对应的线程
    private:
        /*实例化 EventLoop 对象,唤醒_cond上有可能阻塞的线程,并且开始运行EventLoop模块的功能*/
        void ThreadEntry() {
            EventLoop loop;
            {
                std::unique_lock<std::mutex> lock(_mutex);//加锁
                _loop = &loop;
                _cond.notify_all();
            }
            loop.Start();
        }
    public:
        /*创建线程,设定线程入口函数*/
        LoopThread():_loop(NULL), _thread(std::thread(&LoopThread::ThreadEntry, this)) {}
        /*返回当前线程关联的EventLoop对象指针*/
        EventLoop *GetLoop() {
            EventLoop *loop = NULL;
            {
                std::unique_lock<std::mutex> lock(_mutex);//加锁
                _cond.wait(lock, [&](){ return _loop != NULL; });//loop为NULL就一直阻塞
                loop = _loop;
            }
            return loop;
        }
};

class LoopThreadPool {
    private:
        int _thread_count;
        int _next_idx;
        EventLoop *_baseloop;
        std::vector<LoopThread*> _threads;
        std::vector<EventLoop *> _loops;
    public:
        LoopThreadPool(EventLoop *baseloop):_thread_count(0), _next_idx(0), _baseloop(baseloop) {}
        void SetThreadCount(int count) { _thread_count = count; }
        void Create() {
            if (_thread_count > 0) {
                _threads.resize(_thread_count);
                _loops.resize(_thread_count);
                for (int i = 0; i < _thread_count; i++) {
                    _threads[i] = new LoopThread();
                    _loops[i] = _threads[i]->GetLoop();
                }
            }
            return ;
        }
        EventLoop *NextLoop() {
            if (_thread_count == 0) {
                return _baseloop;
            }
            _next_idx = (_next_idx + 1) % _thread_count;
            return _loops[_next_idx];
        }
};
相关推荐
Achou.Wang2 分钟前
Selecting channels:Go 并发里的“多路开关”
服务器·数据库·golang
山岚的运维笔记5 分钟前
Bash 专业人员笔记 -- 第 11 章:`true`、`false` 和 `:` 命令
linux·运维·服务器·开发语言·笔记·学习·bash
ccyl016 分钟前
UOS server 版(摩尔X300显卡)服务器安装显卡驱动
运维·服务器
海兰9 分钟前
使用 OpenTelemetry 与 Elastic APM 追踪 MCP 服务器工具调用
运维·服务器·elasticsearch·wpf
青天飞叶10 分钟前
2026年高性能推理标杆:DreamZero推理服务器深度解析(延迟低至1.2ms,吞吐量提升300%)
运维·服务器
Linux运维技术栈10 分钟前
Jenkins服务器更新密钥后任务构建不了?排查实录与解决方案
服务器·servlet·jenkins
Galsk11 分钟前
Linux零拷贝
java·linux·服务器·面试
我不介意孤独2 小时前
面向华为昇腾 NPU 的企业级 PaddleOCR 推理服务,支持多卡多实例动态扩缩容、高召回 OCR 与生产级部署。
服务器·华为·ocr
uiop_uiop_uiop9 小时前
fnOS LUKS on RAID Storage Pool
服务器
IT大白鼠9 小时前
Linux进程与计划任务管理:技术详解与实战指南
linux·运维·服务器