Linux AIO

什么是AIO?

AIO就是允许应用程序启动一个或多个异步执行的I / O操作。

 

AIO的思想:进程发起I/O操作,而不用阻塞或等待任何操作完成,稍后或在接收到I/O操作完成通知时,进程可以I/O操作结果。

也就是说,你可以在进程读写文件的同时,干你自己相干的事,而不用等待进程读写数据,节省时间。

 

AIO的结构体

struct aiocb {

               int             aio_fildes;     /* 要被读写的文件描述符 */
               off_t           aio_offset;     /* 文件偏移量*/
               volatile void  *aio_buf;        /*读写对应的buf */
               size_t          aio_nbytes;     /* 读写字节数 */
               int             aio_reqprio;    /* 优先级 */
               struct sigevent aio_sigevent;   /* 通知方法 */
           };

其中通知方法一共有三种:

1.通过信号

2.通过启动一个线程

3.不作通知


struct sigevent {
           int          sigev_notify; /* 通知方法 */
           int          sigev_signo;  /* 通知信号 */
           union sigval sigev_value;  /* 传递的数据*/
           void       (*sigev_notify_function) (union sigval);/* 用线程的函数 */
           void        *sigev_notify_attributes;/* 通知线程的属性

       };

 

 AIO接口 API

       aio_read                    异步读

       aio_write                   异步写

       aio_error                   检查异步请求状态

       aio_return                 获得异步返回状态

       aio_suspend             挂起调用进程,直到一个或多个异步请求已经完成(或失败)

       aio_cancel                取消异步I/O请求

       lio_listio                    发起大量I/O操作请求

 

int aio_read(struct aiocb *aiocbp);

这个函数就是异步读取一个描述符

#include <iostream>                                                                  
#include <aio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

using namespace std;
//当操作完成时,会发送信号,然后会执行这个函数
void p(int t,siginfo_t *q,void *r)
{   
    char *c = (char *)q->si_ptr;
    cout << c << endl; 
    cout << "读取完成" << endl;
}
int main()
{
    //注册信号
    struct sigaction act;
    memset(&act,0,sizeof(act));
    act.sa_sigaction = p;
    act.sa_flags = SA_SIGINFO | SA_RESTART;
    sigaction(SIGRTMIN,&act,NULL);
    //int aio_read(struct aiocb *aiocbp);
    struct aiocb aios;
    memset(&aios,0,sizeof(aios));
    aios.aio_fildes = open("www.txt",O_RDONLY);
    if(aios.aio_fildes < 0)
    {
        perror("open err:");
        return -1;
    }
    aios.aio_offset = 0;
    //这个是写入的buf
    char c[100] = { 0 };
    aios.aio_buf = (void *)c;
    aios.aio_nbytes = 100;
    //这是说,执行完成后发送信号
    aios.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
    //这个是发送的信号,我使用kill -l随机取了一个
    aios.aio_sigevent.sigev_signo = SIGRTMIN;
    //这个是发送的值(得了解可靠信号和不可靠信号的知识)
    aios.aio_sigevent.sigev_value.sival_ptr = (void *)c;

    if(aio_read(&aios) < 0)
    {
        perror("aid_read err:");
        return -1;
    }
    cout << "看看谁先执行" << endl;
    sleep(10);
    cout << "Hello world" << endl;
    return 0;
}

注:如果编译时出现错误undefined reference to 'aio_read',那么,很可能是编译时POSIX实时扩展库librt的链接。

在编译时候后面加上 -lrt 

 

不用信号和线程的情况:

    //不用信号,只能执行完其他操作后查看状态
    while(1)
    {   
        int t = aio_error(aios);
        int flag = 0;
        switch(t)
        {   
        case EINPROGRESS:
            cout << "请求尚未完成" << endl;
            break;
        case ECANCELED:
            cout << "请求取消了"  << endl;
            break;
        case -1: 
            perror("aio err:");
            return;
        case 0:
            cout << "请求成功" << endl;
            flag = 1;
            break;
        }   
        if(flag)                                                                     
            break;
    }  

还有就是这个函数,可以 发起大量I/O操作请求

int lio_listio(int mode, struct aiocb *const aiocb_list[],int nitems, struct sigevent *sevp);

其他函数看man手册就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值