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

devtools/2024/12/22 15:02:33/

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

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

设置线程数量:

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

创建线程池:

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

EventLoop对象的分配:

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

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

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

 

 

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

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

 

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

LoopThreadPool模块整体代码:

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];}
};


http://www.ppmy.cn/devtools/101913.html

相关文章

pip package查询网站(性质类似于npmjs.com)

网址&#xff1a;PyPI The Python Package Index python 的依赖包查询网站 就和 node 的 npmjs.com 一样

HTML静态网页成品作业(HTML+CSS)——电影肖申克的救赎介绍设计制作(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

webflux源码解析(4)-异常request处理

目录 1.说明2. 代码路径 1.说明 在webflux接收请求时&#xff0c;第一步实际上 netty-reacto r将 channel 中的字节信息解析成msg(netty-reactor的解析)&#xff0c;进而解析成request&#xff0c;之后才是webflux的处理流程。 实践中发现&#xff0c;当调用接口时若request存…

GRBL接入12V后串口失效问题

1. 问题描述 使用了atmega2560的开发板&#xff0c;烧录了对应的grbl固件&#xff0c;通过串口可以正常访问和控制grbl。 然而&#xff0c;当我接入12V电源并接上电机之后&#xff0c;进行串口控制&#xff0c;会出现几条命令之后&#xff0c;串口突然卡住&#xff0c;无法访问…

【Linux】基本命令(第二篇)

目录 1.命令提示符 2.命令的基本格式 1) 选项的作用 2) 参数的作用 2.cd命令&#xff1a;切换目录 3.pwd命令&#xff1a;显示当前路径 4.ls命令&#xff1a;查看目录下文件 5.mkdir命令&#xff1a;创建目录&#xff08;文件夹&#xff09; 6.rmdir命令&#xff1a;删…

Oracle数据库

注意&#xff1a;其实oracle数据库跟mysql数据库基本语法大致一样只有小部分语言存在差别。 安装PL/SQL Developer 一.数据库实例 1.1 启动数据库实例 一个Oracle实例&#xff08;Oracle Instance&#xff09;有一系列的后台进程&#xff08;Backguound Processes)和内存结构…

devops学习思路

一、关于devops流程 win上建个maven项目&#xff0c;使用win上的nexus私服。 使用git版本管理。 wmware搭建gitlab、jenkins、ldap、artifactory。 做一套简单的流程。 后面可以加代码扫描、单元测试等等功能。 二、maven、nexus私服学习目标 架构课里的课程 API操作&am…

达梦数据库启动与停止

1.1.1数据库启停之菜单方式启动、停止达梦数据库 当数据库服务器是Windows时&#xff0c;开始-->达梦数据库-->点击“DM服务查看器”&#xff0c;找到 “DmService【数据库实例名】” -->右键启动或停止。 下图中数据库实例名是DMSERVER 当数据库服务器是Linux时&…