重写muduo之Thread、EventLoopThread、EventLoopThreadPool

目录

1、概述

2、Thread

2.1 Thread.h

3、EventLoopThread

3.1 EventLoopThread.h

3.2  EventLoopThread.cc

4、 EventLoopThreadPool

4.1 EventLoopThreadPool.h

4.2 EventLoopThreadPool.cc


1、概述

管理事件循环线程的调度的

打包了一个EventLoop和线程,绑定了一个loop跟thread,让这个loop运行在这个thread上,在这个thread里面创建一个loop(one loop per thread)

底层封装的线程

2、Thread

2.1 Thread.h

#pragma once#include "noncopyable.h"#include <functional>
#include <thread>
#include <memory>
#include <string>
#include <atomic>class Thread:noncopyable
{
public:using ThreadFunc=std::function<void()>;//线程函数的函数类型  绑定器和函数对象,就可以传参 explicit Thread(ThreadFunc,const std::string& name=std::string());//构造函数~Thread();void start();//启动当前线程 void join();//当前线程等待其他线程完了再运行下去 bool started()const {return started_;}pid_t tid()const{return tid_;}const std::string& name()const{return name_;}static int numCreated(){return numCreated_;}
private:void setDefaultName();//给线程设置默认的名称bool started_;//启动当前线程 bool joined_;//当前线程等待其他线程完了再运行下去 std::shared_ptr<std::thread> thread_;//自己来掌控线程对象产生的时机pid_t tid_;ThreadFunc func_;//存储线程函数 std::string name_;//调试的时候打印 static std::atomic_int numCreated_;//对线程数量计数 
};

 我们使用C++结合lambda表达式 的方法来实现,非常方便。

3、EventLoopThread

3.1 EventLoopThread.h

#pragma once#include "noncopyable.h"
#include "Thread.h"#include <functional>
#include <mutex>
#include <condition_variable>
#include <string>class EventLoop;class EventLoopThread:noncopyable
{
public:using ThreadInitCallback=std::function<void(EventLoop*)>;EventLoopThread(const ThreadInitCallback& cb=ThreadInitCallback(), //线程初始化的回调 const std::string& name=std::string());~EventLoopThread();EventLoop* startLoop();//开启循环 
private:void threadFunc();//线程函数,创建loop EventLoop* loop_;bool exiting_;//是否退出循环Thread thread_;std::mutex mutex_;std::condition_variable cond_;ThreadInitCallback callback_;//初始化操作 
};

3.2  EventLoopThread.cc

#include "EventLoopThread.h"
#include "EventLoop.h"EventLoopThread::EventLoopThread(const ThreadInitCallback& cb, //线程初始化的回调 const std::string& name):loop_(nullptr),exiting_(false),thread_(std::bind(&EventLoopThread::threadFunc,this),name)//绑定回调函数,mutex_(),cond_(),callback_(cb){}
EventLoopThread::~EventLoopThread()
{exiting_=true;if(loop_!=nullptr){loop_->quit();thread_.join();}
}EventLoop* EventLoopThread::startLoop()//开启循环 
{thread_.start();//启动底层的新线程//启动后执行的是EventLoopThread::threadFuncEventLoop* loop=nullptr;{std::unique_lock<std::mutex> lock(mutex_);while(loop_==nullptr)//loop指针还没有初始化{cond_.wait(lock);挂起,等待}loop=loop_;}return loop;
}//下面这个方法,是在单独的新线程里面运行的
void EventLoopThread::threadFunc()//线程函数,创建loop 
{EventLoop loop;//创建一个独立的eventloop,和上面的线程是一一对应的,one loop per threadif(callback_)//如果有回调{callback_(&loop);//绑定loop做一些事情}{std::unique_lock<std::mutex> lock(mutex_);loop_=&loop;//就是运行在这个线程的loop对象,将这个对象初始化好之后(loop指针指向loop对象),才能唤醒(通知)cond_.notify_one();//唤醒1个线程,被唤醒后去访问loop指针}loop.loop();//EventLoop loop=>Poller.pollstd::unique_lock<std::mutex> lock(mutex_);loop_=nullptr;
}

4、 EventLoopThreadPool

这个很明显,是池的概念。是一个事件线程池,管理eventloop,eventloop绑定的就是一个线程。

用户最开始创建的loop,对应的是一个线程

4.1 EventLoopThreadPool.h

#pragma once
#include "noncopyable.h"#include <functional>
#include <string>
#include <vector>
#include <memory>class EventLoop;
class EventLoopThread;class EventLoopThreadPool:noncopyable
{
public:using ThreadInitCallback=std::function<void(EventLoop*)>;EventLoopThreadPool(EventLoop* baseLoop,const std::string& nameArg);~EventLoopThreadPool();void setThreadNum(int numThreads){numThreads_=numThreads;}void start(const ThreadInitCallback& cb=ThreadInitCallback());//如果工作在多线程中,baseloop_默认以轮询的方式分配channel给subloopEventLoop* getNextLoop();std::vector<EventLoop*> getAllLoops();bool started()const{return started_;}const std::string name() const{return name_;}
private:EventLoop* baseLoop_;//EventLoop loop;std::string name_;bool started_;int numThreads_;int next_;std::vector<std::unique_ptr<EventLoopThread>> threads_;std::vector<EventLoop*> loops_;
};

4.2 EventLoopThreadPool.cc

#include "EventLoopThreadPool.h"
#include "EventLoopThread.h"#include <memory>EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop,const std::string& nameArg):baseLoop_(baseLoop),name_(nameArg),started_(false),numThreads_(0),next_(0){}
EventLoopThreadPool::~EventLoopThreadPool()
{}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());//底层创建线程,绑定一个新的EventLoop,并返回该loop的地址}//整个服务端只有一个线程,运行着baseloopif(numThreads_==0&&cb){cb(baseLoop_);}
}//如果工作在多线程中,baseloop_默认以轮询的方式分配channel给subloop
//通过轮询的方式从子线程中取loop(循环)
//IO线程  baseloop  用作处理用户的连接事件
//工作线程  新创建的loop  用于处理用户的读写事件
EventLoop* EventLoopThreadPool::getNextLoop()
{EventLoop* loop=baseLoop_;if(!loops_.empty())//通过轮询获取下一个处理事件的loop{loop=loops_[next_];next_++;if(next_>=loops_.size()){next_=0;}}return loop;
}std::vector<EventLoop*> EventLoopThreadPool::getAllLoops()
{if(loops_.empty()){return std::vector<EventLoop*>(1,baseLoop_);}else{loops_;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/8563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目经理【过程】原则

系列文章目录 【引论一】项目管理的意义 【引论二】项目管理的逻辑 【环境】概述 【环境】原则 【环境】任务 【环境】绩效 【人】概述 【人】原则 【人】任务 【人】绩效 【过程】概念 【过程】原则 一、质量管理水平、质量管理的发展 1.1 质量管理水平 1.2 质量管理的发展 …

NAS选购全方位解析,性价比才是硬道理 | 2024年618威联通NAS选购攻略

NAS选购全方位解析&#xff0c;性价比才是硬道理 | 2024年618威联通NAS选购攻略 哈喽小伙伴们好&#xff0c;我是Stark-C~&#xff0c;临近618&#xff0c;今天和大家谈谈NAS的选购问题。 关注我的小伙伴都知道&#xff0c;经过我手头折腾的NAS设备非常多&#xff0c;除了群晖…

如果出现一个工具,可以让前端开发彻底不用再手写UI,这个工具意义大吗?干货!

求这样的一个工具&#xff0c;可以让后端开发、嵌入式开发、产品经理、UI设计师都能用&#xff0c;注意&#xff0c;不是在一个简单的静态页生成&#xff0c;也不是类似飞冰那种 generator &#xff0c;而是真正让设计师和开发者在各自的那侧达成自治&#xff0c;可以做到吗&am…

;【排列【

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

C++进阶之路:深入理解编程范式,从面向过程到面向对象(类与对象_上篇)

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

如何使用Tushare+ Backtrader进行股票量化策略回测

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

ICode国际青少年编程竞赛- Python-2级训练场-列表入门

ICode国际青少年编程竞赛- Python-2级训练场-列表入门 1、 Dev.step(3)2、 Flyer.step(1) Dev.step(-2)3、 Flyer.step(1) Spaceship.step(7)4、 Flyer.step(5) Dev.turnRight() Dev.step(5) Dev.turnLeft() Dev.step(3) Dev.turnLeft() Dev.step(7) Dev.turnLeft() Dev.…

【数字经济】上市公司供应链数字化数据(2000-2022)

数据来源&#xff1a; 时间跨度&#xff1a;2000-2022年 数据范围&#xff1a;各上市企业 数据指标&#xff1a; 样例数据&#xff1a; 参考文献&#xff1a;[1]刘海建,胡化广,张树山,等.供应链数字化的绿色创新效应[J].财经研究,2023,49(03):4-18. 下载链接&#xff1a;https:…

Linux(openEuler、CentOS8)基于chrony企业内网NTP服务器搭建实验

一、知识点 chrony 是由 守护进程 chronyd 以及 命令行工具 chronyc 组成的 chronyd 在后台静默运行并通过 123 端口与时间服务器定时同步时间&#xff0c;默认的配置文件是 /etc/chrony.conf chronyc 通过 323 端口与 chronyd 交互&#xff0c;可监控 chronyd 的性能并在运…

基于springboot+vue+Mysql的口腔管理平台

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

【3dmax笔记】026:挤出和壳修改器的使用

文章目录 一、修改器二、挤出三、壳 一、修改器 3ds Max中的修改器是一种强大的工具&#xff0c;用于创建和修改复杂的几何形状。这些修改器可以改变对象的形状、大小、方向和位置&#xff0c;以生成所需的效果。以下是一些常见的3ds Max修改器及其功能&#xff1a; 挤出修改…

Day22 代码随想录打卡|字符串篇---实现 strStr()

题目&#xff08;leecode T28&#xff09;&#xff1a; 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1…

第 8 章 电机测速(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 8.3.3 电机测速01_理论 测速实现是调速实现的前提&#xff0c;本节主要介绍AB相增量式编码器测速原理。 1.概…

可视化面板布局适配屏幕-基于 flexible.js + rem 智能大屏适配

可视化面板布局适配屏幕-基于 flexible.js rem 智能大屏适配 VScode 安装cssrem插件引入flexible.js在之后的开发都使用rem为单位&#xff0c;安装cssrem插件就是为了快捷将px转为rem我们的设计稿是1920px&#xff0c;设置最小宽度为1024px&#xff0c;最后&#xff0c;我们可…

县供电公司员工向媒体投稿发文章用亲身经历告诉你并不难

在县供电公司的日子里,我肩负着一项至关重要的使命——信息宣传工作。这不仅仅是一份职责,更是连接公司与外界的桥梁,通过新闻稿件传递我们的声音,展示我们的成果。然而,回忆起刚刚踏入这个领域的时光,那段经历至今让我感慨万千。 初涉投稿,步履维艰 刚接手这项工作时,我的投稿…

又发现一个ai生成音乐的网站-heymusic

网址 https://heymusic.ai/ 尴尬&#xff0c;不挂梯子能登录进来&#xff0c;但是谷歌账号注册不了&#xff0c;刷新了几遍也没注册上。 看了下价格&#xff0c;应该不是免费的&#xff0c;所以也没了试用的兴趣。 我也不想用别的邮箱注册了&#xff0c;所以只能简单的水一…

频谱分析:深入解析与全面介绍

频谱分析 一、引言 频谱分析&#xff0c;作为一种广泛应用于信号处理和波谱分析的方法&#xff0c;其在现代科技领域的重要性不言而喻。从基础的物理现象到复杂的通信系统&#xff0c;频谱分析都扮演着至关重要的角色。本文将对频谱分析进行深入的解析和全面的介绍&#xff0…

VxTerm使用教程:连接SSH服务端设备,什么是SSH

一、什么是SSH&#xff1f; <摘自百度> 安全外壳协议 SSH&#xff0c;即安全外壳协议&#xff08;Secure Shell&#xff09;&#xff0c;是一种网络协议&#xff0c;用于在计算机网络上提供安全的远程登录和命令执行功能。 SSH通过加密通信通道来保护数据传输&#xff0c…

电-热耦合市场联合出清!考虑均衡约束的综合能源系统电-热分配方法程序代码!

前言 随着现代城市面临环境问题&#xff0c;原来燃煤的水和空间供暖设备已逐渐被电锅炉和热泵等电气设备所取代。此外&#xff0c;集中生产热能并通过管网分配热能的区域供暖系统&#xff0c;由于其更高的效率&#xff0c;在冬季漫长寒冷的国家和地区越来越受欢迎。供暖设备的…

超级大转盘!(html+less+js)(结尾附代码)

超级大转盘&#xff01;&#xff08;结尾附代码&#xff09; 网上看到有人用转盘抽奖&#xff0c;怀疑是不是有问题&#xff0c;为什么每次都中不了&#xff0c;能不能整个转盘自己想中啥中啥&#xff0c;查阅了网上写得好的文章&#xff0c;果然实现了只中谢谢参与&#xff0…