Nginx基础. eventfd, 异步IO 与epoll的相互协作

2024-06-22 19:48

本文主要是介绍Nginx基础. eventfd, 异步IO 与epoll的相互协作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

关于eventfd.
对于eventfd, 这里只是简单的讲它的功能. 看manpage就足够了, 其中的例子也很容易看懂
eventfd函数可以创建一个efd描述符, 该描述符在内核中维护着一个计数器counter.
在调用eventfd时, 可以传入参数指定内核中维护着的计数器的值.
如果这样调用:
      int efd = eventfd(0, 0);
那么计数器值为0.
如果此时调用:
      read(efd, &ret, sizeof(ret)); 
那么会休眠. 直到有人调用:
      int add = 1;write(efd, &add, sizeof(add))
这时候上面的read才会停止休眠, 得到的ret值为1. 如果write写入的add值不是1, 而是5
那么read函数得到的ret值也会是5. read之后, efd对应的内核中的计数器值就回到了0, 此时再次调用:
      read(efd, &ret, sizeof(ret)); 
那么进程又会阻塞. 除非, efd被你设置成了非阻塞... 会返回EAGAIN错误.



关于异步IO
这里将认识异步IO, 以及epoll是如何与异步IO相互协作的.
在linux下, 有两种异步IO. 一种是由glibc实现的aio, 它是直接在用户空间用pthread进行模拟的伪异步IO; 还有一种是内核实现的aio. 相关的系统调用是以 io_xxx 形式出现的.
在nginx中, 采用的是内核实现的aio, 只有在内核中成功完成了磁盘操作, 内核才会通知进程, 进而使磁盘文件的处理与网络事件的处理同样高效.
内核提供的aio的优点是, 能够同时提交多个io请求给内核, 当大量事件堆积到IO设备的队列中时, 内核将发挥出io调度算法的优势, 对到来的事件处理进行优化, 合并等.
这种内核级别的aio缺点也是很明显的, 它是不支持缓存操作的, 即使需要操作的文件块在linux文件缓存中已经存在, 也不会通过读取缓存来代替实际对磁盘的操作, 所以尽管相对于阻塞进程来说有了很大的好转, 但对于单个请求来说, 还是有可能降低实际的处理效率. 因为本可以从缓存中读的数据在使用异步IO后一定会从磁盘读取.
所以异步IO并不是完美的. 如果大部分用户请求对文件的操作都会落到文件缓存中, 那么放弃异步IO可能是更好的选择.
目前, Nginx仅支持读文件的异步IO, 因为正常写入文件往往是写入内存就返回, 相比于异步IO效率明显提高了.


异步IO方法
在理解异步IO方法时, 为了更好的理解这些方法, 与epoll相关方法做比较则更容易理解.
int io_setup(unsigned nr_events, aio_context_t *ctxp);初始化异步IO上下文. 与epoll相比, 类似epoll_create. nr_events表示异步IO上下文可以处理事件的最小个数通过ctxp获得的上下文描述符与epoll_create返回的描述符类似, 贯穿始终.
int io_submit(aio_context_t ctx_id, long nr, struct iocb **iocbpp);提交文件异步IO操作. iocbpp是提交的事件数组的首个元素地址, nr是提交的事件个数返回值表示成功提交的事件个数. 类似epoll中的 epoll_ctl + EPOLL_CTL_ADD
int io_cancel(aio_context_t ctx_id, struct iocb *iocb, struct io_event *result);取消某个IO操作类似epoll中的epoll_ctl + EPOLL_CTL_DEL
int io_getevents(aio_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout);从已完成的文件异步IO操作队列中读取操作其中, min_nr表示至少获取min_nr个事件; nr表示至多获取nr个事件; events是IO操作完成的事件数组类似epoll中的epoll_wait
int io_destroy(aio_context_t ctx);销毁异步IO上下文.

对于一个进程来说, 通常一个异步IO就可以了, 因为一个异步IO可以同时包含很多异步IO操作.
在调用io_setup初始化完成异步IO上下文后, 将会使用io_submit提交异步IO操作.
其中的struct iocb结构体如下:
struct iocb {//存储业务需要的指针. 在Nginx中, 这个字段通常存储对应ngx_event_t对象的指针.//它实际上与io_getevents中返回的io_event结构体的data成员是完全一致的.uint64_t aio_data;//操作码.  比如IO_CMD_PREAD指定异步读操作;  IO_CMD_PWRITE异步写操作;  IO_CMD_FSYNC强制同步等...uint16_t aio_lio_opcode;//请求的优先级int16_t aio_reqprio; //文件描述符uint32_t aio_fields;//读写操作对应的用户态缓冲区.uint64_t aio_buf;//读写操作的字节长度uint64_t aio_nbytes;uint64_t aio_offset;//表示可以设置为IOCB_FLAG_RESFD, 它会告诉内核当有异步IO请求处理完成时使用eventfd进行通知//可与epoll配合使用. 下面会涉及到uint32_t aio_flags;//表示当使用IOCB_FLAG_RESFD标志时, 用于进行事件通知的句柄uint64_t aio_resfd;...
};
在设置好iocb结构体后, 就可以向异步IO提交事件了. 也可以使用io_cancel将已经提交的事件取消.
那么在异步IO操作完成后, 如何使用i

这篇关于Nginx基础. eventfd, 异步IO 与epoll的相互协作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python WebSockets 库从基础到实战使用举例

《PythonWebSockets库从基础到实战使用举例》WebSocket是一种全双工、持久化的网络通信协议,适用于需要低延迟的应用,如实时聊天、股票行情推送、在线协作、多人游戏等,本文给大家介... 目录1. 引言2. 为什么使用 WebSocket?3. 安装 WebSockets 库4. 使用 We

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

Nginx添加内置模块过程

《Nginx添加内置模块过程》文章指导如何检查并添加Nginx的with-http_gzip_static模块:确认该模块未默认安装后,需下载同版本源码重新编译,备份替换原有二进制文件,最后重启服务验... 目录1、查看Nginx已编辑的模块2、Nginx官网查看内置模块3、停止Nginx服务4、Nginx