Linux异步IO+实例(POSIX IO与 libaio)

本文介绍了Linux异步IO的基本API,包括aio_error、aio_read、aio_write和aio_suspend等,并通过实例演示了如何使用。还探讨了异步IO通知机制,如信号处理和线程回调。最后,文章提到了libaio,一种内核级的异步IO库,以及其相对于用户层模拟异步IO的优势和限制。
摘要由CSDN通过智能技术生成

异步IO基本API

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

上述API调用都会用到 struct aiocb 结构体:

struct aiocb {
   int             aio_fildes;     //文件描述符
   off_t           aio_offset;     //文件偏移量
   volatile void  *aio_buf;        //缓冲区
   size_t          aio_nbytes;     //数据长度
   int             aio_reqprio;    //请求优先级
   struct sigevent aio_sigevent;   //通知方式
   int             aio_lio_opcode; //要执行的操作
};

编译时加参数 -lrt


aio_error

检查异步请求状态

int aio_error(const struct aiocb *aiocbp);
返回值 含义
EINPROGRESS 该请求尚未完成
ECANCELED 该请求被撤销
0 请求成功完成
出错 错误信息存入errno中

aio_read 异步读请求

int aio_read(struct aiocb *aiocbp);

例子:读取test.txt 文件

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h>
#include<aio.h>
#include<stdlib.h>
#include<strings.h>

#define BUFSIZE   256

int main()
{
    struct aiocb    cbp;
    int             fd,ret;
    int             i = 0;

    fd = open("test.txt",O_RDONLY);

    if(fd < 0)
    {
        perror("open error\n");
    }

    //填充struct aiocb 结构体 
    bzero(&cbp,sizeof(cbp));
    //指定缓冲区
    cbp.aio_buf = (volatile void*)malloc(BUFSIZE+1);
    //请求读取的字节数
    cbp.aio_nbytes = BUFSIZE;
    //文件偏移
    cbp.aio_offset = 0;
    //读取的文件描述符
    cbp.aio_fildes = fd;
    //发起读请求
    ret = aio_read(&cbp);
    if(ret < 0)
    {
        perror("aio_read error\n");
        exit(1);
    }

    //查看异步读取的状态,直到读取请求完成
    for(i = 1;aio_error(&cbp) == EINPROGRESS;i++)
    {
        printf("No.%3d\n",i);
    }
    //读取返回值
    ret = aio_return(&cbp);
    printf("return %d\n",ret);

//    sleep(1);   
    printf("%s\n",(char*)cbp.aio_buf);
    close(fd);
    return 0;
}

这里写图片描述

从上图看出,循环检查了3次异步读写的状态,指定的256字节才读取完毕,最后返回读取的字节数256。

如果注释掉异步读的状态检查:

    ...

    //查看异步读取的状态,直到读取请求完成
/*    for(i = 1;aio_error(&cbp) == EINPROGRESS;i++)
    {
        printf("No.%3d\n",i);
    }
    ret = aio_return(&cbp);
    printf("return %d\n",ret);
*/
    ...

这里写图片描述

发现什么都没输出,这是因为程序结束的时候,异步读请求还没完成,所以buf缓冲区还没有读进去数据。

如果将上面代码中的 sleep 的注释去掉,让异步请求发起后,程序等待1秒后再输出,就会发现成功读取到了数据。

用GDB单步跟踪上面程序,当发起异步读请求时:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值