[muduo网络库]——muduo库EventLoopThreadPool类(剖析muduo网络库核心部分、设计思想)

本文主要是介绍[muduo网络库]——muduo库EventLoopThreadPool类(剖析muduo网络库核心部分、设计思想),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

接着之前我们[muduo网络库]——muduo库EventLoopThread类(剖析muduo网络库核心部分、设计思想),我们接下来继续看muduo库中的EventLoopThreadPool类,它和Thread以及EventLoopThread类息息相关。

EventLoopThreadPool类

事件循环线程池,管理所有客户端连接,每个线程都有唯一一个事件循环,可以调用setThreadNum设置线程的数目。线程池中每一个线程都有一个自己的EventLoop,而每一个EventLoop底层都是一个epoll,它利用了自身的epoll在没有事件的时候阻塞住,在有事件发生的时候,epoll监听到了事件就会去处理事件。

重要成员变量

EventLoop *baseLoop_;  //主线程loop
std::string name_;
bool started_; //标记当前状态 即IO线程是否开始运行
int numThreads_; //线程池中线程的数量
int next_;  //负载均衡用
std::vector<std::unique_ptr<EventLoopThread>> threads_;//创建事件的线程
std::vector<EventLoop*> loops_; //事件线程里面EventLoop的指针,每个EventLoopThread线程对应的EventLoop保存在loops_中
  • 具体含义如注释所示

重要成员函数

  • 设置底层线程的数量,状态,名字
void setThreadNum(int numThreads) { numThreads_ = numThreads;}
bool started() const { return started_;}
const std::string name() const { return name_;}
  • 启动线程池,实际上创建numThreads个线程,并让每个eventloopthread调用startLoop()
void EventLoopThreadPool::start(const ThreadInitCallback &cb)
{started_=true;for(int i=0; i<numThreads_; i++){char buf[name_.size() + 32];snprintf(buf,sizeof buf,"%s%d",name_.c_str(),i);EventLoopThread *t =new EventLoopThread(cb,buf);threads_.push_back(std::unique_ptr<EventLoopThread>(t)); //事件循环线程loops_.push_back(t->startLoop()); }//整个服务端只有一个线程,运行着baseloopif (numThreads_ == 0 && cb){cb(baseLoop_);//执行}
}
  1. 设置当前状态为true,根据需要的线程数numThreads_,创建线程
  2. 在for循环中,先创建一个EventLoopThread对象,构造线程池内线程集合
  3. 调用EventLoopThread::startLoop(),创建线程,绑定一个新的EventLoop,并返回loop地址,放入loops_中,loops_是一个std::vector<EventLoop*>类型,把每个EventLoopThread线程对应的EventLoop保存在loops_中。
  4. 如果没有其他线程,只有主线程的话,直接调用callback
  • 以轮询的方式分配channel给subloop
EventLoop* EventLoopThreadPool::getNextLoop()
{EventLoop* loop = baseLoop_;if(!loops_.empty())// 通过轮询,获取下一个处理事件的loop{loop = loops_[next_];++next_;if(next_ >= loops_.size()){next_ = 0;}}return loop;
}

注意: 在TcpServer::newConnection 会通过EventLoop *ioLoop = threadPool_->getNextLoop();初始时loop被赋值为baseLoop_,也就是主线程的loop,如果我们设置子线程为零的话程序也可正常运行,也就是说,getNextLoop的实现意味着muduo是支持单线程的;
如果loops_不为空,loop = loops_[next_],ioLoop就得到了一个subloop

花了很长时间在思考这个cb(baseLoop_)是为什么呢?(个人理解,如果大家觉得有错,麻烦指正)
  1. 在TcpServer::start(),启动IO线程池 threadPool_->start(threadInitCallback_); cb=threadInitCallback_;
  2. 来到了EventLoopThreadPool::start()中,创建一个EventLoopThread对象EventLoopThread *t =new EventLoopThread(cb,buf); ,在这里callback_(cb),先把cb给到了callback_
  3. 接着EventLoopThread::startLoop(),中调用 Thread::start()
  4. 在EventLoopThread的构造函数中,thread_(std::bind(&EventLoopThread::threadFunc,this),name),绑定了threadFunc,在Thread构造函数中func_(std::move(func)),所以会调用EventLoopThread::threadFunc()函数,这里创建了一个EventLoop,并给了callback_;
  5. 所以如果有其他线程,就创建一个loop给回去,没有就会给回去baseLoop_;
  6. EventLoopThreadPool里面的loops_就存了每个EventLoopThread线程对应的EventLoop;
  7. 然后loop_->runInLoop(std::bind(&Acceptor::listen,acceptor_.get()));

代码地址:https://github.com/Cheeron955/mymuduo/tree/master

好了~ 关于muduo库的EventLoopThreadPool类就剖析到这里,与它相关的Thread,EventLoopThread也都完结了,这部分其实有一点不知所云,希望大家发现错误能够批评指正。最后,除去TcpServer,我们就剩下InetAddress类了,下一篇我们来剖析InetAddress类,然后就从整个服务器流程来讲TcpServer ~ 我们下一节见 ~~

这篇关于[muduo网络库]——muduo库EventLoopThreadPool类(剖析muduo网络库核心部分、设计思想)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991391

相关文章

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

hdu1496(用hash思想统计数目)

作为一个刚学hash的孩子,感觉这道题目很不错,灵活的运用的数组的下标。 解题步骤:如果用常规方法解,那么时间复杂度为O(n^4),肯定会超时,然后参考了网上的解题方法,将等式分成两个部分,a*x1^2+b*x2^2和c*x3^2+d*x4^2, 各自作为数组的下标,如果两部分相加为0,则满足等式; 代码如下: #include<iostream>#include<algorithm

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

poj 3181 网络流,建图。

题意: 农夫约翰为他的牛准备了F种食物和D种饮料。 每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。 问最多能有多少头牛可以同时得到喜欢的食物和饮料。 解析: 由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。 如下建图: s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t 所以分配一下点: s  =  0, 牛1= 1~