linux下aio异步读写详解与实例

1.为什么会有异步I/O

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

2.异步I/O的基本概念

所谓异步I/O即我们在调用I/O操作时(读或写)我们的程序不会阻塞在当前位置,而是在继续往下执行。例如当我们调用异步读API aio_read()时,程序执行此代码之后会接着运行此函数下面的代码,并且与此同时程序也在进行刚才所要读的文件的读取工作,但是具体什么时候读完是不确定的

3.异步aio的基本API

API函数 说明
aio_read 异步读操作
aio_write 异步写操作
aio_error 检查异步请求的状态
aio_return 获得异步请求完成时的返回值
aio_suspend 挂起调用进程,直到一个或多个异步请求已完成
aio_cancel 取消异步请求
lio_list 发起一系列异步I/O请求

上述的每个API都要用aiocb结构体赖进行操作
aiocb的结构中常用的成员有

struct aiocb
{
    //要异步操作的文件描述符
    int aio_fildes;
    //用于lio操作时选择操作何种异步I/O类型
    int aio_lio_opcode;
    //异步读或写的缓冲区的缓冲区
    volatile void *aio_buf;
    //异步读或写的字节数
    size_t aio_nbytes;
    //异步通知的结构体
    struct sigevent aio_sigevent;
}

4异步I/O操作的具体使用

(1)异步读aio_read

aio_read函数请求对一个文件进行读操作,所请求文件对应的文件描述符可以是文件,套接字,甚至管道其原型如下

int aio_read(struct aiocb *paiocb);

该函数请求对文件进行异步读操作,若请求失败返回-1,成功则返回0,并将该请求进行排队,然后就开始对文件的异步读操作
需要注意的是,我们得先对aiocb结构体进行必要的初始化
具体实例如下

aio_read

#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/types.h>
#include<fcntl.h>
#include<aio.h>


#define BUFFER_SIZE 1024

int MAX_LIST = 2;

int main(int argc,char **argv)
{
    //aio操作所需结构体
    struct aiocb rd;

    int fd,ret,couter;

    fd = open("test.txt",O_RDONLY);
    if(fd < 0)
    {
        perror("test.txt");
    }



    //将rd结构体清空
    bzero(&rd,sizeof(rd));


    //为rd.aio_buf分配空间
    rd.aio_buf = malloc(BUFFER_SIZE + 1);

    //填充rd结构体
    rd.aio_fildes = fd;
    rd.aio_nbytes =  BUFFER_SIZE;
    rd.aio_offset = 0;

    //进行异步读操作
    ret = aio_read(&rd);
    if(ret < 0)
    {
        perror("aio_read");
        exit(1);
    }

    couter = 0;
//  循环等待异步读操作结束
  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 中,完成异步读写的一种方法是使用 aio_read 和 aio_write 函数。这些函数使用 Linux 内核提供的异步输入/输出(AIO)接口,可以在进行 I/O 操作时不阻塞进程,从而提高系统的性能和吞吐量。 异步读写文件的一般步骤如下: 1. 打开文件,并初始化异步读取或写入结构体。 2. 调用 aio_read 或 aio_write 函数进行异步读写操作。 3. 使用 aio_error 和 aio_return 函数获取异步读写的结果。 4. 关闭文件。 以下是一个简单的示例,演示如何在 Linux 中完成异步读写: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <aio.h> #define BUFSIZE 1024 int main(int argc, char *argv[]) { int fd; struct aiocb aio; char buffer[BUFSIZE]; int ret; if (argc < 2) { printf("Usage: %s <filename>\n", argv[0]); exit(EXIT_FAILURE); } // 打开文件 if ((fd = open(argv[1], O_RDONLY)) == -1) { perror("open"); exit(EXIT_FAILURE); } // 初始化异步读取结构体 memset(&aio, 0, sizeof(struct aiocb)); aio.aio_fildes = fd; aio.aio_buf = buffer; aio.aio_nbytes = BUFSIZE; aio.aio_offset = 0; // 异步读取文件 if (aio_read(&aio) == -1) { perror("aio_read"); exit(EXIT_FAILURE); } // 等待异步读取完成 while ((ret = aio_error(&aio)) == EINPROGRESS); if (ret != 0) { perror("aio_error"); exit(EXIT_FAILURE); } // 获取异步读取结果 if ((ret = aio_return(&aio)) == -1) { perror("aio_return"); exit(EXIT_FAILURE); } // 关闭文件 close(fd); printf("Read %d bytes from file %s.\n", ret, argv[1]); exit(EXIT_SUCCESS); } ``` 以上代码实现了从一个文件中异步读取数据,并将读取的数据存储到 buffer 中。在代码中,首先打开文件,并使用 aio_read 函数异步读取文件,并将读取的数据存储到 buffer 中。最后,使用 aio_error 和 aio_return 函数获取异步读取的结果,并关闭文件。 需要注意的是,以上代码中只是一个简单的示例,实际使用时还需要对错误进行处理,例如当 aio_read 或 aio_write 函数返回 EINPROGRESS 时,需要等待异步读取或写入完成。此外,还需要实现循环读取和写入文件,直到文件全部读取或写入完成。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值