epoll并发编程

epoll并发编程

  • epoll并发编程背景知识
    • epoll 的特点
    • epoll 的工作原理
    • epoll 和 select/poll 的区别
  • epoll并发服务器思路
  • 重点代码分析
  • git地址
  • 参考书目

epoll并发编程背景知识

epoll 是 Linux 中用于处理大量文件描述符的 I/O 事件通知机制。在传统的 I/O 模型中,一般使用 select 或 poll 来进行多路复用,但随着连接数的增加,它们的性能开始下降。而 epoll 的设计旨在解决这个问题,提高大规模并发的网络应用性能。

epoll 的特点

高性能: epoll 可以有效处理大量的连接,且随着连接数增加,性能基本保持稳定。
事件驱动: epoll 是事件驱动的,只有当有事件发生时才会通知应用程序,而不是轮询所有文件描述符。
支持水平触发和边缘触发: epoll 支持两种触发模式。在水平触发模式下,只要有数据可读或可写,就会通知应用程序;而在边缘触发模式下,只在状态发生变化时通知,需要手动清除事件。

epoll 的工作原理

创建 epoll 句柄: 应用程序通过 epoll_create 创建一个 epoll 句柄。
添加文件描述符: 使用 epoll_ctl 将文件描述符添加到 epoll 句柄中,同时指定关注的事件类型(读、写、异常等)。
等待事件发生: 应用程序使用 epoll_wait 等待事件发生。当文件描述符上发生关注的事件时,epoll_wait 将返回,同时告诉应用程序是哪些文件描述符发生了事件。
处理事件: 应用程序得知有事件发生后,可以执行相应的操作,如读取数据、发送数据等。

epoll 和 select/poll 的区别

效率: epoll 的效率更高,因为它不需要轮询所有文件描述符,而是在事件发生时通知应用程序。
连接数: epoll 能够处理大规模的并发连接,而 select 和 poll 的性能随着连接数的增加而下降。
触发模式: epoll 支持水平触发和边缘触发,而 select 和 poll 只支持水平触发。
文件描述符管理: epoll 使用一组文件描述符来管理事件,而 select 和 poll 使用单一的文件描述符集合。

epoll并发服务器思路

初始化: 创建一个监听套接字,该套接字用于接受客户端的连接请求。同时,你需要创建一个 epoll 实例,用于注册和监听套接字上的事件。

监听套接字设置为非阻塞: 使用 fcntl 函数将监听套接字设置为非阻塞模式,以便能够使用非阻塞 accept。

创建线程池: 初始化一个线程池,线程池的作用是处理具体的连接请求。线程池中的每个线程都可以处理一个独立的连接。

循环处理事件: 在一个主循环中使用 epoll_wait 等待事件的发生。当有新的连接请求到达时,你可以使用线程池中的一个线程来处理该连接。

处理连接: 当新的连接到达时,线程池中的一个线程会处理该连接。这可能涉及到接收、发送数据,或执行其他相关任务。

使用线程池的好处: 线程池可以帮助你充分利用系统的多核心资源,提高并发处理能力。每个线程独立处理一个连接,避免了在单线程中处理所有连接时的性能瓶颈。

注意线程安全: 在处理连接时,需要确保线程安全性。可以使用互斥锁等机制来保护共享资源,以防止多个线程同时访问导致的问题。

重点代码分析

这部分没有展示具体的实现代码,而是把一些业务逻辑省略掉了,只展示了epoll和线程池相关的核心代码,具体实现代码见git仓库。

初始化: 创建一个监听套接字,使用 epoll_create 创建一个 epoll 句柄,以及一个线程池。

int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
// 设置 listen_sock 为非阻塞
fcntl(listen_sock, F_SETFL, fcntl(listen_sock, F_GETFL, 0) | O_NONBLOCK);
epoll_fd = epoll_create(MAX_EVENTS);  // MAX_EVENTS 是事件表的大小
ThreadPool pool(NUM_THREADS);  // NUM_THREADS 是线程池的大小

绑定和监听: 将监听套接字绑定到指定地址,并开始监听。

struct sockaddr_in server_addr;
// 设置 server_addr
bind(listen_sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
listen(listen_sock, SOMAXCONN);

添加监听套接字到 epoll 事件表中

struct epoll_event ev;
ev.events = EPOLLIN | EPOLLET;  // 设置边缘触发模式
ev.data.fd = listen_sock;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_sock, &ev);

事件循环: 使用 epoll_wait 等待事件的发生,根据不同的事件类型执行相应的操作。

while (true) {struct epoll_event events[MAX_EVENTS];int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);for (int i = 0; i < num_events; ++i) {if (events[i].data.fd == listen_sock) {// 处理新连接handle_new_connection(listen_sock);} else {// 处理其他事件pool.enqueue(handle_event, events[i].data.fd);}}
}

线程池处理事件: 每个事件都由线程池中的线程来处理,这样可以充分利用多核 CPU 的性能。

void handle_event(int client_sock) {// 处理读写事件,例如接收数据、发送数据等// 可以根据业务需要在这里进行具体的操作
}

git地址

https://gitee.com/xinquanfu/epoll-chat

参考书目

Stevens, W. R., Fenner, B., & Rudoff, A. M. .《UNIX网络编程 卷1: 套接字联网API》.
Chen, S. 《Linux多线程服务端编程:使用muduo C++网络库》.
游双. 《Linux高性能服务器编程》.
莫烦周. 《深入理解Linux内核》.
云天励.《Linux性能优化实战》.
Stevens, W. R. 《TCP/IP详解 卷1:协议》.
Richter, J. M. 《C++网络编程:构建高效且灵活的网络系统》.

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

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

相关文章

Screenshot-to-code开源项目mac上实践

github上的开源项目&#xff0c;看介绍可以将设计ui图片转换为 HTML 和 CSS 源码地址&#xff1a; GitCode - 开发者的代码家园 我的mac安装了2.7和3.11&#xff0c;就用3吧直接上代码 安装 pip3 install keras tensorflow pillow h5py jupyter 报错 ERROR: Could not in…

Linux驱动开发之Linux内核中的中断处理与等待队列以及相关API和例程分析

目录 中断的特点 Linux中的中断类型 相关API函数 gpio_to_irq() enable_irq() disable_irq() request_irq() free_irq() 中断的使用 等待队列 DECLARE_WAIT_QUEUE_HEAD() wait_event_interruptible() wake_up_interruptible() 中断相关例程 例程分析 源码分享 …

linux实用技巧:ubuntu18.04安装samba服务器实现局域网文件共享

Ubuntu安装配置Samba服务与Win10共享文件 Chapter1 Ubuntu18.04安装配置Samba服务与Win10共享文件一、什么是Samba二、安装Samba1、查看是否有安装samba2、安装samba 三、配置Samba服务1、创建共享目录&#xff08;以samba_workspaces为例&#xff09;2、为samba设置登录用户3、…

独立站的个性化定制:提升用户体验的关键

随着电子商务的竞争加剧&#xff0c;用户体验成为了企业赢得市场的关键因素之一。独立站作为企业品牌形象和产品展示的重要平台&#xff0c;其个性化定制的程度直接影响着用户体验。本文将探讨独立站的个性化定制如何提升用户体验&#xff0c;并通过代码示例说明实现个性化定制…

学习动态规划不同路径、最小路径和、打家劫舍、打家劫舍iii

学习动态规划|不同路径、最小路径和、打家劫舍、打家劫舍iii 62 不同路径 动态规划&#xff0c;dp[i][j]表示从左上角到(i,j)的路径数量dp[i][j] dp[i-1][j] dp[i][j-1] import java.util.Arrays;/*** 路径数量* 动态规划&#xff0c;dp[i][j]表示从左上角到(i,j)的路径数量…

计算机网络-动态路由

网络层协议&#xff1a;ip&#xff0c;ospf&#xff0c;rip&#xff0c;icmp共同组成网络层体系 ospf用于自治系统内部。 一个路由器或者网关需要能够支持多个不同的路由协议&#xff0c;以适应不同的网络环境。特别是在连接不同自治系统的边缘路由器或边界网关的情况下&#…

MongoDB聚合:$merge 阶段(2)

$merge的用途是把聚合管道产生的结果写入指定的集合&#xff0c;有时候可以用$merge来做物化视图。下面是$merge的一些例子。 举例 按需物化视图&#xff1a;创建集合 当输出集合不存在时&#xff0c;$merge将自动创建。首先在zoo数据库的salaries集合中填充员工和部门历史数…

Golang解决跨域问题【OPTIONS预处理请求】

Golang解决跨域问题 前置知识&#xff1a;跨域问题产生条件及原因 跨域是是因为浏览器的同源策略限制&#xff0c;是浏览器的一种安全机制&#xff0c;服务端之间是不存在跨域的。 所谓同源指的是两个页面具有相同的协议、主机和端口&#xff0c;三者有任一不相同即会产生跨域…

Autosar MCAL-RH850P1HC Mcu配置

文章目录 McuModuleConfigurationCvm Diag Lock BitCvm Out Mask DiagCvm Out Mask FbistCvm Output FilterCvm Reset EnableNumber Of Mcu ModesRam SectorsReset SettingSw Reset TriggerMcuClockSettingConfigClock Setting Id

数据库原理与应用快速复习(期末急救)

文章目录 第一章数据库系统概述数据、数据库、数据库管理系统、数据定义、数据组织、存储和管理、数据操纵功能、数据库系统的构成数据管理功能、数据库管理的3个阶段以及特点数据库的特点、共享、独立、DBMS数据控制功能数据库的特点 数据模型两类数据模型、逻辑模型主要包括什…

2023 IoTDB Summit:天谋科技 CTO 乔嘉林《IoTDB 企业版 V1.3: 时序数据管理一站式解决方案》...

12 月 3 日&#xff0c;2023 IoTDB 用户大会在北京成功举行&#xff0c;收获强烈反响。本次峰会汇集了超 20 位大咖嘉宾带来工业互联网行业、技术、应用方向的精彩议题&#xff0c;多位学术泰斗、企业代表、开发者&#xff0c;深度分享了工业物联网时序数据库 IoTDB 的技术创新…

【Web2D/3D】CSS3的2D/3D转换、过渡、动画(第一篇)

1. 前言 本篇开始介绍Web2D和3D相关基础知识&#xff0c;会从CSS3的2D/3D转换、过渡、动画&#xff0c;讲到Canvas 2D图形绘制&#xff0c;再到SVG&#xff0c;最后到WebGL。 坐标系&#xff1a;左上点是坐标原点(0,0)&#xff0c;x轴正方向向右&#xff0c;y轴正方向向下&…

STL——查找算法

算法简介&#xff1a; find ——//查找元素find_if ——//按条件查找元素adjacent_find ——//查找相邻重复元素binary_search ——//二分查找法count ——//统计元素个数count_if ——//按条件统计元素个数 1.find 函数原型&#xff1a; find(iterator beg, iterator end,…

(学习打卡1)重学Java设计模式之设计模式介绍

前言&#xff1a;听说有本很牛的关于Java设计模式的书——重学Java设计模式&#xff0c;然后买了(*^▽^*) 开始跟着小傅哥学Java设计模式吧&#xff0c;本文主要记录笔者的学习笔记和心得。 打卡&#xff01;打卡&#xff01; 设计模式介绍 一、设计模式是什么&#xff1f; …

【Matlab】基于遗传算法优化BP神经网络 (GA-BP)的数据时序预测

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88682033 一&#xff0c;概述 基于遗传算法优化BP神经网络 (GA-BP) 的数据时序预测是一种常用的机器学习方法&#xff0c;用于预测时间序列数据的趋势和未来值。 在使用这种方法之前&#xff0c;需要将时间序…

Linux:apache优化(4)—— 隐藏版本号

运行环境 yum -y install apr apr-devel cyrus-sasl-devel expat-devel libdb-devel openldap-devel apr-util-devel apr-util pcre-devel pcre gcc make zlib-devel 源码包配置 ./configure --prefix/usr/local/httpd --enable-cgi --enable-rewrite --enable-so --enabl…

oracle-检查点队列

检查点队列也在buffer cache上&#xff0c;和LRU&#xff0c;CBC。。。一样&#xff0c;也在一个链上。 检查点队列链也链的是脏块&#xff0c;也就是脏块不仅链在LRUW上&#xff0c;也在这里。 在LRUW上是按照冷热排列。而检查点队列链是按照脏块的第一次脏的时间顺序排序。 R…

20231230 SQL基础50题打卡

20231230 SQL基础50题打卡 570. 至少有5名直接下属的经理 表: Employee ---------------------- | Column Name | Type | ---------------------- | id | int | | name | varchar | | department | varchar | | managerId | int | -----------…

2024年单片机毕业设计选题物联网计算机电气电子类

博主八年毕业设计辅导经验&#xff0c;安全 可靠。 题目一&#xff1a;基于单片机的PM2.5空气质量检测仪器 选 1.用到ADC0832模数转换芯片&#xff0c;数据更加精准。 2.使用夏普传感器的GP2Y1010AUOF粉尘传感器实时检测空气中的PM2.5值并通过1602显示出来&#xff0c;检测…

【Spark精讲】一文讲透SparkSQL聚合过程以及UDAF开发

SparkSQL聚合过程 这里的 Partial 方式表示聚合函数的模式&#xff0c;能够支持预先局部聚合&#xff0c;这方面的内容会在下一节详细介绍。 对应实例中的聚合语句&#xff0c;因为 count 函数支持 Partial 方式&#xff0c;因此调用的是 planAggregateWithoutDistinct 方法&a…