【在Linux世界中追寻伟大的One Piece】多路转接epoll

目录

1 -> I/O多路转接之poll

1.1 -> poll函数接口

1.2 -> poll的优点

1.3 -> poll的缺点

1.4 -> poll示例

1.4.1 -> 使用poll监控标准输入

2 -> I/O多路转接之epoll

2.1 -> 初识epoll

2.2 -> epoll的相关系统调用

2.2.1 -> epoll_create

2.2.2 -> epoll_ctl

2.2.3 -> epoll_wait

2.3 -> epoll工作原理

2.4 -> epoll优点


1 -> I/O多路转接之poll

1.1 -> poll函数接口

#include <poll.h>

int poll(struct pollfd* fds, nfds_t nfds, int timeout);

// pollfd 结构
struct pollfd 
{
	int fd; /* file descriptor */
	short events; /* requested events */
	short revents; /* returned events */
};

参数说明:

  • fds是一个poll函数监听的结构列表。每一个元素中,包含了三部分内容:文件描述符,监听的事件集合,返回的事件集合。
  • nfds表示fds数组的长度。
  • timeout表示poll函数的超时时间,单位是毫秒(ms)。

events和revents的取值:

事件描述是否可作为输入是否可作为输出
POLLIN数据(包括普通数据和优先数据)可读
POLLRDNORM普通数据可读
POLLRDBAND优先级带数据可读(Linux不支持)
POLLPRI高优先级数据可读,比如TCP带外数据
POLLOUT数据(包括普通数据和优先数据)可写
POLLWRNORM普通数据可写
POLLWRBAND优先级带数据可写

POLLRDHUPTCP连接被对方关闭,或者对方关闭了写操作。它由GNU引入
POLLERR错误

POLLHUP挂起。比如管道的写端被关闭后,读端描述符上将收到POLLHUP事件
POLLNVAL文件描述符没有打开

返回结果:

  • 返回值小于0,表示出错。
  • 返回值等于0,表示poll函数等待超时。
  • 返回值大于0,表示poll由于监听的文件描述符就绪而返回。

1.2 -> poll的优点

不同于select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现。

  • pollfd结构包含了要监视的event和发生的event,不再使用select"参数-值"传递的方式。接口使用比select更方便。
  • poll并没有最大数量限制(但是数量过大后性能也是会下降)。

1.3 -> poll的缺点

poll中监听的文件描述符数目增多时:

  • 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
  • 每次调用poll都需要把大量的pollfd结构从用户态拷贝到内核中。
  • 同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降。

1.4 -> poll示例

1.4.1 -> 使用poll监控标准输入

#include <poll.h>
#include <unistd.h>
#include <stdio.h>

int main() 
{
	struct pollfd poll_fd;

	poll_fd.fd = 0;
	poll_fd.events = POLLIN;
	for (;;) 
	{
		int ret = poll(&poll_fd, 1, 1000);
		if (ret < 0) 
		{
			perror("poll");
			continue;
		}

		if (ret == 0) 
		{
			printf("poll timeout\n");
			continue;
		}

		if (poll_fd.revents == POLLIN) 
		{
			char buf[1024] = { 0 };
			read(0, buf, sizeof(buf) - 1);

			printf("stdin:%s", buf);
		}
	}
}

2 -> I/O多路转接之epoll

2.1 -> 初识epoll

epoll是Linux内核中提供的一种高效的IO多路复用机制,它专为处理大量文件描述符而设计。相比于传统的select和poll机制,epoll在存在大量并发连接且只有少数连接活跃时,能够显著提高系统的CPU利用率。epoll的关键优势在于它在获取就绪事件时,不会遍历所有被监听的文件描述符集,而是只会遍历那些被设备IO事件异步唤醒(通过CPU中断机制)而加入就绪链表的文件描述符集。

按照man手册的说法:是为处理大批量句柄而作了改进的poll。

它是在2.5.44内核中被引进的(epoll(4)is a new API introduced in Linux kernel 2.5.44)它几乎具备了之前所说的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法。

2.2 -> epoll的相关系统调用

2.2.1 -> epoll_create

int epoll_create(int size);

创建一个epoll的句柄。

  • 自从linux2.6.8之后,size参数是被忽略的。
  • 用完之后,必须调用close()关闭。

2.2.2 -> epoll_ctl

int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event);

epoll的事件注册函数。

它不同于select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。

  • 第一个参数是epoll_create()的返回值(epoll 的句柄)。
  • 第二个参数表示动作,用三个宏来表示。
  • 第三个参数是需要监听的fd。
  • 第四个参数是告诉内核需要监听什么事。

第二个参数的取值:

  • EPOLL_CTL_ADD:注册新的fd到epfd中。
  • EPOLL_CTL_MOD:修改已经注册的fd的监听事件。
  • EPOLL_CTL_DEL:从epfd中删除一个fd。

struct epoll_event结构如下:

typedef union epoll_data
{
	void* ptr;
	int fd;
	uint32_t u32;
	uint64_t u64;
} epoll_data_t;

struct epoll_event
{
	uint32_t events; //Epoll events
	epoll_data_t data; //User data variable
}_EPOLL_PACKED;

events可以是以下几个宏的集合:

  • EPOLLIN:表示对应的文件描述符可以读(包括对端SOCKET正常关闭)。
  • EPOLLOUT:表示对应的文件描述符可以写。
  • EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来)。
  • EPOLLERR:表示对应的文件描述符发生错误。
  • EPOLLHUP:表示对应的文件描述符被挂断。
  • EPOLLET:将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
  • EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里。

2.2.3 -> epoll_wait

int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);

收集在epoll监控的事件中已经发送的事件。

  • 参数events是分配好的epoll_event结构体数组。
  • epoll将会把发生的事件赋值到events数组中(events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮助我们在用户态中分配内存)。
  • maxevents告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size。
  • 参数timeout是超时时间(毫秒,0会立即返回,-1是永久阻塞)。
  • 如果函数调用成功,返回对应I/O上已准备好的文件描述符数目,如返回0表示已超时, 返回小于0表示函数失败。

2.3 -> epoll工作原理

当某一进程调用epoll_create方法时,Linux内核会创建一个eventpoll结构体,这个结构体中有两个成员与epoll的使用方式密切相关。

struct eventpoll 
{
	/*红黑树的根节点,这颗树中存储着所有添加到 epoll 中的需要监控的事件*/
	struct rb_root rbr;

	/*双链表中则存放着将要通过 epoll_wait 返回给用户的满足条件的事件*/
	struct list_head rdlist;
};
  • 每一个epoll对象都有一个独立的eventpoll结构体,用于存放通过epoll_ctl方法向epoll对象中添加进来的事件。
  • 这些事件都会挂载在红黑树中,如此,重复添加的事件就可以通过红黑树而高效的识别出来(红黑树的插入时间效率是lgn,其中n为树的高度)。
  • 而所有添加到epoll中的事件都会与设备(网卡)驱动程序建立回调关系,也就是说,当响应的事件发生时会调用这个回调方法。
  • 这个回调方法在内核中叫ep_poll_callback,它会将发生的事件添加到rdlist双链表中。
  • 在epoll中,对于每一个事件,都会建立一个epitem结构体。
struct epitem 
{
	struct rb_node rbn;//红黑树节点
	struct list_head rdllink;//双向链表节点
	struct epoll_filefd ffd; //事件句柄信息
	struct eventpoll* ep; //指向其所属的 eventpoll 对象
	struct epoll_event event; //期待发生的事件类型
}
  • 当调用epoll_wait检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可。
  • 如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户。这个操作的时间复杂度是O(1)。

总结一下,epoll的使用过程就是三部曲:

  • 调用epoll_create创建一个epoll句柄。
  • 调用epoll_ctl,将要监控的文件描述符进行注册。
  • 调用epoll_wait,等待文件描述符就绪。

2.4 -> epoll优点

  • 接口使用方便:虽然拆分成了三个函数,但是反而使用起来更方便高效。不需要每次循环都设置关注的文件描述符,也做到了输入输出参数分离开。
  • 数据拷贝轻量:只在合适的时候调用EPOLL_CTL_ADD将文件描述符结构拷贝到内核中,这个操作并不频繁(而select/poll都是每次循环都要进行拷贝)。
  • 事件回调机制:避免使用遍历,而是使用回调函数的方式,将就绪的文件描述符结构加入到就绪队列中,epoll_wait返回直接访问就绪队列就知道哪些文件描述符就绪。这个操作时间复杂度O(1)。即使文件描述符数目很多,效率也不会受到影响。
  • 没有数量限制:文件描述符数目无上限。

感谢各位大佬支持!!!

互三啦!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙华为商城APP案例

模拟器运行效果如下&#xff1a; 鸿蒙版APP-华为商城-演示视频

在公司中,如何表现出自己的高情商,学会这三句话就可以了

在职场中&#xff0c;高情商的重要性不言而喻。它能帮助你更好地处理人际关系&#xff0c;提升团队协作效率&#xff0c;还能让你在职场上获得更多的机会。 在职场中&#xff0c;适时地给予同事、上级和下属赞美、感谢和鼓励&#xff0c;能够拉近彼此的距离&#xff0c;增强团…

linux进行磁盘分区

1. lsblk查看磁盘信息 2. 进行磁盘分区 fdisk /dev/sdb 输入n 创建一个新的分区 输入p 创建一个主分区 输入1-4的一个分区号 输入开始扇地址 输入分区的大小 100G就是分100G出来 输入wq保存 3. 设置磁盘格式 /dev/sdb1为刚分出来的磁盘空间 mkfs -t ext4 /dev/sdb1 4…

边缘计算在智能物流中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 边缘计算在智能物流中的应用 边缘计算在智能物流中的应用 边缘计算在智能物流中的应用 引言 边缘计算概述 定义与原理 发展历程 …

恒创科技:什么是 RAID 3 ? RAID 3、4 和5之间有什么区别?

RAID 是一种存储数据以提高性能并减少数据丢失的特定技术。您可以根据自己的需求选择多种 RAID 类型。RAID 3 是列表中比较有效的类型之一。本文将重点介绍这种特定的 RAID 技术&#xff0c;并比较 RAID 3、4 和 5。 RAID 3 的定义 RAID 3 是一种特定的磁盘配置&#xff0c;用于…

光模块基础知识

1. 光模块的封装 光模块是光收发模块的简称&#xff0c;主要根据不同的外型来区分&#xff0c;而在同一外型中&#xff0c;又有着多种规格&#xff1b;在数据通信领域&#xff0c;最常见的光模块&#xff08;根据外型区分&#xff09;分别是SFF、GBIC、SFP、和XFP、QSFP 、XEN…

推荐一款DBF文件查看器:DBF Viewer 2000

DBF Viewer 2000是一款强大、简洁且易于使用的 DBF(Clipper、dBase、FoxBase、Foxpro、Visual Foxpro、Visual DBase、VO、DB2K)文件浏览器和编辑器。 软件特点&#xff1a; - 能够快速、有效地浏览和编辑各种类型的 DBF 文件。 - 支持多种文件格式&#xff0c;包括 dBase、V…

javascript-Web APLs (四)

日期对象 用来表示时间的对象 作用&#xff1a;可以得到当前系统时间 在代码中发现了 new 关键字时&#xff0c;一般将这个操作称为 实例化 //创建一个时间对象并获取时间 //获得当前时间 const date new Date() //获得指定时间 const date new Date(2006-6-6) console.log(…

云计算在智能交通系统中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 云计算在智能交通系统中的应用 云计算在智能交通系统中的应用 云计算在智能交通系统中的应用 引言 云计算概述 定义与原理 发展历…

图像算法之 OCR 识别算法:原理与应用场景

一、引言 在当今数字化时代&#xff0c;图像信息的处理和识别变得越来越重要。光学字符识别&#xff08;Optical Character Recognition&#xff0c;OCR&#xff09;算法作为一种能够将图像中的文字转换为可编辑文本的技术&#xff0c;正广泛应用于各个领域。从文档数字化到自…

云计算:定义、类型及对企业的影响

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 云计算&#xff1a;定义、类型及对企业的影响 云计算&#xff1a;定义、类型及对企业的影响 云计算&#xff1a;定义、类型及对企…

Chromium127编译指南 Mac篇(六)- 编译优化技巧

1. 前言 在Chromium127的开发过程中&#xff0c;优化编译速度是提升开发效率的关键因素。本文将重点介绍如何使用ccache工具来加速C/C代码的编译过程&#xff0c;特别是在频繁切换分支和修改代码时。通过合理配置和使用这些工具&#xff0c;您将能够显著减少编译时间&#xff…

打假官方咨询(续)

大家还记得我们的上一次测试吗&#xff1a;9.9大还是9.11大&#xff0c;我又把这个问题拎了出来&#xff0c;看一下各家AI的最新表现&#xff1a; 商量&#xff08;出自商汤科技&#xff09;&#xff1a; 我们可以发现&#xff0c;商量好像没长记性&#xff0c;上次错了&#…

AFL++实战入门与afl-fuzz流程解析(源码流程图)

简介 本项目为模糊测试的零基础教学,适合了解 pwn 且会使用 Linux 的 gcc、gdb 的读者。模糊测试旨在通过向程序投喂数据使其崩溃,从而获取崩溃样本以寻找程序漏洞。本文前半部分介绍 AFL++ 的 docker 环境配置,帮助读者解决入门时的环境和网络问题; 后半部分全面解析 afl…

单体架构 IM 系统之长轮询方案设计

在上一篇技术短文&#xff08;单体架构 IM 系统之核心业务功能实现&#xff09;中&#xff0c;我们讨论了 “信箱模型” 在单体架构 IM 系统中的应用&#xff0c;“信箱模型” 见下图。 客户端 A 将 “信件” 投入到客户端 B 的 “信箱” 中&#xff0c;然后客户端 B 去自己的 …

计算机图形学 实验二 三维模型读取与控制

目录 一、实验内容 二、具体内容 (在实验2.3的基础上进行修改) 1、OFF格式三维模型文件的读取 2、三维模型的旋转动画 3、键盘鼠标的交互 4、模型的修改 三、代码 一、实验内容 读取实验提供的off格式三维模型&#xff0c;并对其赋色。利用鼠标和键盘的交互&#xff0…

利用AI制作《职业生涯规划PPT》,10分钟完成

职业生涯规划是大学生活中非常重要的一环。通过制定职业规划&#xff0c;你能够明确未来的职业目标、认清自身的优劣势&#xff0c;进而制定切实可行的计划&#xff0c;以便顺利踏上职业发展的道路。而制作一份精美的职业生涯规划PPT&#xff0c;能有效帮助你在面试、职业规划报…

CKA认证 | Day2 K8s内部监控与日志

第三章 Kubernetes监控与日志 1、查看集群资源状态 在 Kubernetes 集群中&#xff0c;查看集群资源状态和组件状态是非常重要的操作。以下是一些常用的命令和解释&#xff0c;帮助你更好地管理和监控 Kubernetes 集群。 1.1 查看master组件状态 Kubernetes 的 Master 组件包…

EasyExcel级联下拉

代码 package com.xc.excel.select;import com.alibaba.excel.EasyExcel; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileOutputStream; import java.i…

快速入门CSS

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗 如有错误&#xff0c;欢迎指出~ 目录 CSS css的三种引入方式 css书写规范 选择器分类 标签选择器 class选择器 id选择器 复合选择器 通配符选择器 color颜色设置 border边框设置 width/heigth 内/外边距 C…