muduo网络库剖析——通道Channel类

muduo网络库剖析——通道Channel类

  • 前情
    • 从muduo到my_muduo
  • 概要
    • 事件种类
    • channel
  • 框架与细节
    • 成员
    • 函数
    • 细节实现
    • 使用方法
  • 源码
  • 结尾

前情

从muduo到my_muduo

作为一个宏大的、功能健全的muduo库,考虑的肯定是众多情况是否可以高效满足;而作为学习者,我们需要抽取其中的精华进行简要实现,这要求我们足够了解muduo库。

做项目 = 模仿 + 修改,不要担心自己学了也不会写怎么办,重要的是积累,学到了这些方法,如果下次在遇到通用需求的时候你能够回想起之前的解决方法就够了。送上一段话!

在这里插入图片描述

概要

事件种类

epoll_event是Linux操作系统中的一个数据结构,用于表示一个I/O事件。它在使用epoll多路复用技术时作为参数传递给相关的函数,以便在事件发生时通知应用程序。
epoll_event结构体的定义如下:

struct epoll_event {  __uint32_t events;  /* Epoll events */  epoll_data_t data;  /* User data variable */  
};

其中,events表示事件,例如EPOLLIN(需要读取数据的情况)、EPOLLOUT(输出缓冲为空,可以立即发送数据的情况)等。data是用户数据变量,可以使用union epoll_data来定义,其中ptr可以指向任何类型的用户数据,fd表示文件描述符,u32和u64分别表示一个32位和64位的无符号整数。

当应用程序注册了某个文件描述符到一个epoll实例上时,就可以通过epoll_event结构体来指定对应的事件以及关联的用户数据。当这些事件发生时,epoll系统调用会返回对应的epoll_event结构体,以便应用程序处理事件。

总的来说,epoll_event结构体是Linux系统中实现事件驱动编程的一个关键数据结构,通过它可以将多个I/O事件集中处理,提高了程序的效率和响应性。

channel

而channel和event一一映射,通过channel能够获取到event中的events,即感兴趣的事件,通过channel也可以改变events感兴趣的事件。同时Poller监听,如果有事件发生,那么该事件所对应channel也会调用所相应发生事件的回调函数。这就是channel类的主要作用,起到了一个代表event,但大于event作用的这样一个类。

框架与细节

成员

在这里插入图片描述
channel中成员包括自己所属的事件循环,还有channel对应的套接字,用来监听;以及该channel中event所感兴趣的事件,和真正监听到的事件,以及channel此时在Poller中处于什么状态,对应着Poller是否在监听对应的event.
在这里插入图片描述
代表感兴趣事件的类型。设为static变量,类使用。
在这里插入图片描述
以及相关的函数回调。

函数

包括一系列的函数调用声明,以及读写事件的确认与设置,感兴趣事件对应event修改,事件发生时对应回调函数触发。完成channel的与event对应,以及channel能够作为触发对象针对event监听到的事件进行函数回调触发等功能。

细节实现

如果h文件中不会规定某类的大小,或者只用到了某类的指针,我们可以通过声明class而不是include头文件的来减少头文件信息的暴露。比如:
当中的EventLoop类在h文件中只涉及指针,更多细节在cc文件中实现。那我们在头文件中只写class EventLoop;而在cc文件中再包含上EventLoop.h即可。
在这里插入图片描述
在这里插入图片描述
update函数和remove函数表示着通道的更新和删除,我们统一的实现是在时间循环类EventLoop趋势线这两个函数,所以channel和Poller中的对通道的更改会调用EventLoop类中的对channel更改函数。

使用方法

源码

//Channel.h
#pragma once#include <functional>
#include <sys/epoll.h>#include "noncopyable.h"
#include "Timestamp.h"
#include "Log.h"class EventLoop;  class Channel : noncopyable {
public:using EventCallback = std::function<void()>;using ReadEventCallback = std::function<void(Timestamp)>;Channel(EventLoop* loop, int fd) : loop_(loop), fd_(fd), events_(0), status_(0) {}~Channel() = default;int fd() const { return fd_; }EventLoop* loop() const { return loop_; }int status() const { return status_; }int events() const { return events_; }bool isReading() const { return events_ & kReadEvent; }bool isWriting() const { return events_ & kWriteEvent; }bool isNoneEvent() const { return events_ == kNoneEvent; }void enableReading() { events_ |= kReadEvent; update(); }void enableWriting() { events_ |= kWriteEvent; update(); }void disableReading() { events_ &= ~kReadEvent; update(); }void disableWriting() { events_ &= ~kWriteEvent; update(); }void disableAll() { events_ = kNoneEvent; update(); }void setReadCallback(const ReadEventCallback& cb) { readCallback_ = cb; }void setWriteCallback(const EventCallback& cb) { writeCallback_ = cb; }void setErrorCallback(const EventCallback& cb) { errorCallback_ = cb; }void setCloseCallback(const EventCallback& cb) { closeCallback_ = cb; }void remove();void set_revents(int revents) { revents_ = revents; }void set_status(int status) { status_ = status; }void handleEventWithGuard(Timestamp receiveTime);
private:void update();EventLoop* loop_;int fd_;int events_;int revents_;int status_;static const int kNoneEvent;static const int kReadEvent;static const int kWriteEvent;EventCallback writeCallback_;EventCallback errorCallback_;EventCallback closeCallback_;ReadEventCallback readCallback_;
};//Channel.cc
#include "Channel.h"
#include "EventLoop.h"void Channel::update() {loop_->updateChannel(this);
}void Channel::remove() {loop_->removeChannel(this);
}void Channel::handleEventWithGuard(Timestamp receiveTime) {LOG_INFO("%s--%s--%d : channel handle revents : %d\n", __FILE__, __FUNCTION__, __LINE__, revents_);if ((revents_ & EPOLLHUP) && !(revents_ & EPOLLIN)) {if (closeCallback_) closeCallback_();}else if (revents_ & EPOLLERR) {if (errorCallback_) errorCallback_();}else if (revents_ & EPOLLIN) {if (readCallback_) readCallback_(receiveTime);}else if (revents_ & EPOLLOUT) {if (writeCallback_) writeCallback_();}
}

结尾

以上就是通道Channel类的相关介绍,以及我在进行项目重写的时候遇到的一些问题,和我自己的一些心得体会。发现写博客真的会记录好多你的成长,而且对于一个好的项目,写博客也是证明你确实有过深度思考,并且在之后面试或者工作时遇到同样的问题能够进行复盘的一种有效的手段。所以,希望uu们也可以像我一样,养成写博客的习惯,逐渐脱离菜鸡队列,向大佬前进!!!加油!!!

也希望我能够完成muduo网络库项目的深度学习与重写,并在功能上能够拓展。也希望在完成这个博客系列之后,能够引导想要学习muduo网络库源码的人,更好地探索这篇美丽繁华的土壤。致敬chenshuo大神!!!

鉴于博主只是一名平平无奇的大三学生,没什么项目经验,所以可能很多东西有所疏漏,如果有大神发现了,还劳烦您在评论区留言,我会努力尝试解决问题!

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

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

相关文章

多线程-Thread类及常见方法

目录 1.什么是Thread类 1.1Thread 的常⻅构造⽅法 1.2 Thread 的⼏个常⻅属性 2.启动⼀个线程 - start() 经典面试题&#xff1a;start 和run 区别 3.中断⼀个线程 方法一&#xff1a; 方法二: 4.等待⼀个线程 - join() 1.什么是Thread类 Thread类是Java编程语言中的一个重…

图像去噪——CTNet网络推理测试(详细图文教程)

目录 一、CTNet二、源码包准备2.1 测试集2.2 模型权重 三、环境准备四、推理测试4.1 配置参数修改4.2 官网测试4.2.1 测试当通道图像4.2.1.1 命令方式测试4.2.1.2 Configuration配置测试4.2.1.3 测试结果 4.2.2 测试彩色图像4.2.2.1 命令方式测试4.2.2.2 Configuration配置测试…

性能优化-HVX架构简介

来自 「发表于知乎专栏《移动端算法优化》」 本文主要介绍Hexagon DSP的HVX技术&#xff0c;旨在通过简单的语言讲清HVX技术。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&#xff09;开…

Elasticsearch 入门向使用

文章目录 ElasticSearch简介倒排索引安装(单节点)分词器kibana与Mysql概念上的对比索引库CRUD文档CRUDDSL查询相关性算分Function Score Query自定义算分Boolean Query 搜索结果处理排序分页高亮 数据聚合 aggregations自动补全数据同步集群 ElasticSearch 简介 Elasticsearc…

轻松掌握AI辅助设计微信红包封面并快速过审

【无矶之谈】轻松使用AI设计微信红包封面/动态封面并快速过审 关注本公众号梦无矶测开实录&#xff0c;2024年1月21日之后关注最新的文章&#xff0c;后台回复封面红包&#xff0c;即可免费领取本号专属微信红包封面。&#xff08;目前我过审的有五个封面&#xff0c;其中一个…

vue项目执行依赖安装(npm i或npm install )报ls-remote -h -t异常

从git拉取的vue项目执行依赖安装时一直报错&#xff0c; 报错如下图&#xff1a;首先&#xff0c;查看了node版本、npm配置的镜像地址均没找到解决办法。 在命令行中直接输入git发现提示于是从网上搜到了一个博文https://blog.csdn.net/weixin_49159364/article/details/118198…

仰暮计划|“每天清晨五六点钟,爷爷早早起床去田地里采摘蔬菜”

★ 我的奶奶出生于1955年&#xff0c;在我眼里是十分伟大的女性。身处在有六个兄弟姐妹的大家庭里&#xff0c;她从小就肩负起了照顾家人的重任。充满朝气的她&#xff0c;在上学和照顾弟弟妹妹之间穿梭。然而&#xff0c;在她将要上小学五年级的时候&#xff0c;文化大革命的爆…

[绍棠] docxtemplater实现纯前端导出word

1.下载需要的依赖 2.util文件夹下创建doc.js文件 doc.js import docxtemplater from docxtemplater import PizZip from pizzip import JSZipUtils from jszip-utils import { saveAs } from file-saver import ImageModule from "docxtemplater-image-module-free"…

力扣hot100 最长有效括号 动态规划

Problem: 32. 最长有效括号 文章目录 思路Code 思路 &#x1f468;‍&#x1f3eb; 参考题解 Code ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) class Solution {public int longestValidParentheses(String s){int n s.length();…

Python武器库开发-武器库篇之Fofa-API使用(四十六)

Python武器库开发-武器库篇之Fofa-API使用(四十六) FOFA&#xff08;FOcus Observation of Futures Assets&#xff09;是一款专业的网络资产搜索引擎&#xff0c;旨在帮助企业发现和评估网络上的潜在安全风险。FOFA的基本原理是通过搜索引擎的方式&#xff0c;按照关键词对互…

【Redis】更改redis中的value值

今天继续进步一点点~~ 背景&#xff1a;今天有个前端的同事问我&#xff0c;能不能在Redis中他本人登录公众号的 sessionID 加上一列openID 于是我上网查了一堆在Redis里面的命令&#xff0c;以及不同的客户端怎么输入命令&#xff0c;但是后来问了下同事&#xff0c;他就给我…

PDshell16逆向PostgreSQL 工程显示字段comment备注

现状&#xff1a;当刚逆向成功的表结构是没有原来表结构中的&#xff0c;comment备注如下 然后pd逆向工程的sql已经返回了这个备注的含义 解决方案&#xff1a; 1、设置显示注释列 tools——Display Preferences…如下 勾选-按照下面得方式勾选这三个 复制这里的VBS脚本&a…

OpenVINS学习7——评估工具的简单使用

前言 OpenVINS自带评估工具&#xff0c;这里记录一下使用方法&#xff0c;我是以VIRAL数据集为例&#xff0c;但是目前仍然有问题&#xff0c;发现误差很大&#xff0c;我还没搞明白哪里出了问题。 工具介绍 主要参考 https://docs.openvins.com/eval-error.html https://bl…

Windows和Linux访问不了GitHub的解决方法

一、Windows访问不了GitHub 问题描述 使用Windows访问GitHub时&#xff0c;出现如下情况&#xff0c;显示无法访问。 解决方案&#xff1a; 打开域名查询网站&#xff1a;https://tool.chinaz.com/dns 输入GitHub的域名&#xff0c;点击立即检测。 出现如下页面&#xff0c…

实验五 PLSQL编程

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…

git设置代理

git设置代理 git config --global http.proxy 127.0.0.1:7890git查询代理 git config --global http.proxy git取消代理 git config --global --unset http.proxy

【核心复现】基于改进鲸鱼优化算法的微网系统能量优化管理matlab

目录 一、主要内容 1 冷热电联供型微网系统 2 长短期记忆网络(Long Short Term Memory, LSTM) 3 改进鲸鱼优化算法 二、部分代码 三、运行结果 四、下载链接 一、主要内容 该程序为《基于改进鲸鱼优化算法的微网系统能量优化管理》matlab代码&#xff0c;主要内容如下&…

事件驱动架构

请求驱动 服务注册&#xff0c;服务发现&#xff0c;虽然调用地址隐藏了&#xff0c;但是调用stub必须相同。 rpc通信&#xff0c;远程调用。 生产者和消费者要有相同的stub存根。 消费者和生产者的调用接口是耦合的。 事件驱动 核心&#xff1a;上下游不进行通信 中间通过M…

Ubuntu安装最新版Docker和Docker-Compose

ubuntu环境搭建专栏&#x1f517;点击跳转 Ubuntu系统环境搭建&#xff08;十&#xff09;——Ubuntu安装最新版Docker和Docker Compose 文章目录 Ubuntu系统环境搭建&#xff08;十&#xff09;——Ubuntu安装最新版Docker和Docker Compose1.添加Docker库1.1 安装必要的证书并…

实验六 模式对象管理与安全管理

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…