仿Muduo的高并发服务器:LoopThread模块及其ThreadPool模块
本期我们接着深入项目编写相关代码上传至作者的个人gitee仿muduo服务器: 本项目致力于实现一个仿造muduo库的简易并发服务器为个人项目参考即可喜欢请点个赞谢谢目录LoopThread模块设计思想源码LoopThreadPool模块设计思想源码LoopThread模块设计思想目标将EventLoop模块与线程整合起来EventLoop模块与线程是一一对应的。EventLoop模块实例化的对象在构造的时候就会初始化_thread_id而后边当运行一个操作的时候判断当前是否运行在eventLoop模块对应的线程中就是将线程ID与EventLoop模块中的thread_id进行一个比较相同就表示在同一个线程不同就表示当前运行线程并不是EventLoop线程。含义EventLoop模块在实例化对象的时候必须在线程内部。EventLoop实例化对象时会设置自己的thread_id。如果我们先创建了多个EventLoop对象然后创建了多个线程将各个线程的id重新给EventLoop进行设置存在问题在构造EventLoop对象到设置新的thread_id期间将是不可控的。因此我们必须先创建线程然后在线程的入口函数中去实例化EventLoop对象源码LoopThread.hpp#pragma once #include EventLoop.hpp #include thread #include mutex #includecondition_variable #include atomic #include functional namespace ImMuduo { class LoopThread { public: LoopThread(); ~LoopThread(); //获取EventLoop智能指针 EventLoop* GetLoop(); private: //线程入口函数——创建EventLoop对象并启动模块功能 void ThreadEntry(); private: std::thread thread_;//EventLoop线程 std::unique_ptrEventLoop loop_;//EventLoop智能指针,需要在线程内实例化 //用于实现Loop操作的同步,避免在构造函数中创建EventLoop对象,导致线程创建失败 std::mutex mutex_; std::condition_variable condition_; }; }LoopThread.cpp#include LoopThread.hpp namespace ImMuduo { LoopThread::LoopThread() :thread_(LoopThread::ThreadEntry, this) ,loop_(nullptr) ,mutex_() ,condition_() {} LoopThread::~LoopThread() { if (loop_) { loop_-Stop(); } if (thread_.joinable()) { thread_.join(); } } EventLoop* LoopThread::GetLoop() { EventLoop* loop nullptr; { std::unique_lockstd::mutex lock(mutex_); condition_.wait(lock, [this]() { return loop_ ! nullptr; }); loop loop_.get(); } return loop; } void LoopThread::ThreadEntry() { auto loop std::make_uniqueEventLoop(); { std::unique_lockstd::mutex lock(mutex_); loop_ std::move(loop); condition_.notify_one(); } loop_-Start(); } }LoopThreadPool模块设计思想针对LoopThread设计一个线程池LoopThreadPool模块对所有的LoopThread进行管理及分配功能1. 线程数量可配置0个或多个注意事项在服务器中主从Reactor模型是主线程只负责新连接获取从属线程负责新连接的事件监控及处理因此当前的线程池有可能从属线程会数量为0也就是实现单Reactor服务器一个线程及负责获取连接也负责连接的处理2. 对所有的线程进行管理其实就是管理0个或多个LoopThread对象3. 提供线程分配的功能当主线程获取了一个新连接需要将新连接挂到从属线程上进行事件监控及处理假设有0个从属线程则直接分配给主线程的EventLoop进行处理假设有多个从属线程则采用RR轮转思想进行线程的分配将对应线程的EventLoop获取到设置给对应的Connection源码LoopThreadPool.hpp#pragma once #includeLoopThread.hpp namespace ImMuduo { class LoopThreadPool { public: LoopThreadPool(EventLoop* eventLoop); ~LoopThreadPool(); void SetThreadNum(int thread_num); void CreateThreads(); EventLoop* NextLoop(); private: EventLoop* loop_; int next_idx_; int thread_num_; std::vectorstd::unique_ptrLoopThread threads_; std::vectorEventLoop* loops_; }; }LoopThreadPool.cpp#includeLoopThreadPool.hpp namespace ImMuduo { LoopThreadPool::LoopThreadPool(EventLoop* eventLoop) :next_idx_(0), thread_num_(0), loop_(eventLoop) {} LoopThreadPool::~LoopThreadPool() { } void LoopThreadPool::SetThreadNum(int thread_num) { thread_num_ thread_num; } void LoopThreadPool::CreateThreads() { if (thread_num_ 0) return; threads_.reserve(thread_num_); loops_.reserve(thread_num_); for (int i 0; i thread_num_; i) { auto t std::make_uniqueLoopThread(); loops_.push_back(t-GetLoop()); threads_.push_back(std::move(t)); } } EventLoop* LoopThreadPool::NextLoop() { if (loops_.empty()) return loop_; EventLoop* ret loops_[next_idx_]; next_idx_ (next_idx_ 1) % static_castint(loops_.size()); return ret; } }本期内容到这里就结束了喜欢请点个赞谢谢封面图自取
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2592987.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!