Linux下AIO服务设计框架

一. 对于异步I/O的概述aio异步读写是在Linux内核2.6之后才正式纳入其标准。之所以会增加此模块,是因为众所周知我们计算机CPU的执行速度远大于I/O读写的执行速度,如果我们用传统的阻塞式或非阻塞式来操作I/O的话,那么我们在同一个程序中(不用多线程或多进程)就不能同时操作俩个以上的文件I/O,每次只能对一个文件进行I/O操作,很明显这样效率很低下(因为CPU速度远大于I/O操作的速度,所...
摘要由CSDN通过智能技术生成

一. 对于异步I/O的概述

aio异步读写是在Linux内核2.6之后才正式纳入其标准。之所以会增加此模块,是因为众所周知我们计算机CPU的执行速度远大于I/O读写的执行速度,如果我们用传统的阻塞式或非阻塞式来操作I/O的话,那么我们在同一个程序中(不用多线程或多进程)就不能同时操作俩个以上的文件I/O,每次只能对一个文件进行I/O操作,很明显这样效率很低下(因为CPU速度远大于I/O操作的速度,所以当执行I/O时,CPU其实还可以做更多的事)。因此就诞生了相对高效的异步I/O。

二.与其他I/O模型的类比

在介绍AIO之前,先来概括一下Linux下其他的I/O模型。

如图每个 I/O 模型都有自己的使用模式,它们对于特定的应用程序都有自己的优点。下面一一来介绍:

同步阻塞 I/O 模型

在这个模型中,用户空间的应用程序执行一个系统调用,这会导致应用程序阻塞。这意味着应用程序会一直阻塞,直到系统调用完成为止(数据传输完成或发生错误)。调用应用程序处于一种不再消费 CPU 而只是简单等待响应的状态,因此从处理的角度来看,这是非常有效的。


同步非阻塞 I/O

       同步阻塞 I/O 的一种效率稍低的变种是同步非阻塞 I/O。在这种模型中,设备是以非阻塞的形式打开的。这意味着 I/O 操作不会立即完成,read操作可能会返回一个错误代码,说明这个命令不能立即满足(EAGAIN 或 EWOULDBLOCK)



异步阻塞 I/O
IO多路复用(复用的select线程)。I/O复用模型会用到select、poll、epoll函数,这几个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。对于每个提示符来说,我们可以获取这个描述符可以写数据、有读数据可用以及是否发生错误的通知。


(上述图文转自:https://blog.csdn.net/secretx/article/details/53668827)

epoll总结

epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知.
epoll的优点:
*  没有最大并发连接的限制,能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口)。
*  效率提升,不是轮询的方式,只管你“活跃”的连接,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数。
*  内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。

>>>表面上看epoll的性能最好,但是在连接数少并且连接都十分活跃的情况下,select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。


  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Linux中关闭AIO异步输入输出)可以通过以下步骤实现: 1. 首先,确保在程序中调用了`aio_cancel`函数来取消所有未完成的异步操作。这将确保在关闭AIO之前,所有的异步操作都被终止。 2. 然后,使用`aio_error`函数来检查异步操作的错误状态。如果返回值为`EINPROGRESS`,表示异步操作仍在进行中,需要等待操作完成。 3. 使用`aio_return`函数来获取异步操作的返回值。如果返回值大于0,表示操作已完成,并且可以获取到返回的数据。 4. 最后,使用`aio_suspend`函数来等待所有异步操作完成。这将阻塞程序,直到所有异步操作都完成。 5. 在所有异步操作都完成后,可以关闭文件描述符和释放相关的资源。 以下是一个示例代码,展示了如何关闭AIO: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <aio.h> #include <fcntl.h> int main() { struct aiocb cb = {0}; int fd = open("test.txt", O_RDONLY); if (-1 == fd) { printf("文件打开失败:%m\n"); exit(-1); } printf("文件打开成功!\n"); // 异步读取文件数据 cb.aio_fildes = fd; cb.aio_nbytes = BUFF_SIZE; cb.aio_offset = 0; int r = aio_read(&cb); if (-1 == r) { printf("异步读取失败:%m\n"); close(fd); exit(-2); } printf("异步读取成功!\n"); // 取消未完成的异步操作 aio_cancel(fd, &cb); // 等待所有异步操作完成 aio_suspend(&cb, 1, NULL); // 获取异步操作的返回值 r = aio_return(&cb); if (r > 0) { printf("拿到了数据: r:%d bytes, data: %s\n", r, cb.aio_buf); } // 关闭文件描述符和释放内存 close(fd); free(cb.aio_buf); return 0; } ``` 请注意,以上代码仅展示了关闭AIO的基本步骤,并不包含完整的错误处理和资源释放。在实际应用中,需要根据具体情况进行适当的错误处理和资源管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值