Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6097381
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: LINUX

2013-10-09 12:07:35

原文地址:aio 简介 作者:anqiu1987

名字:

    aio: POSIX 异步IO

描述:

     aio接口允许应用程序同时运行一个或者多个IO操作(例如在后台)。应用程序可以选择不同IO完成的通知方式:通过信号,线程的实例化,
或者不需要通知。


aio包括一个结构体:
    

#include struct aiocb { /* 成员的顺序依赖于具体的实现 */
     int aio_fildes;                                                         / * 文件描述符 */
     off_t aio_offset;                                                      /* 文件偏移量*/
     volatile void *aio_buf;                                           /* buffer */
     size_t aio_nbytes;                                                   /* buffer的字节数 */
     int aio_reqprio;                                                     /* 请求优先级 */
     struct sigevent aio_sigevent;                            /* 通知的方法 */
     int aio_lio_opcode;                                             /* 需要执行的操作 */
     /* 其它的暂时不需要的成员没有显示*/ };

    /*aio_lio_opcode 可以执行的操作 */
     enum { LIO_READ, LIO_WRITE, LIO_NOP };

aio包括的函数:
     int aio_read(struct aiocb *aiocbp);
                   加入一个读的请求,类似与read(fd,buf,count),aiocb结构中的 aio_fildes对应于fd,aio_buf对应于buf,aio_nbytes对应于count。
                  该读操作开始与绝对的文件偏移量aio_offset处。一旦加入队列,该函数就会返回,可以通过函数aio_error查询进度,通过aio_retrun查询
                  返回状态。同步的通知通过aiocb的信号aio_sigevent来设置。
     int aio_write(struct aiocb* aiocbp);
                  该函数类似与aio_read,但是当指定了O_APPEND的时候,数据会写到文件末尾。
     int aio_fsync(int op, struct aiocb *aiocbp);
                  该操作吧所有的正在排队的aio操作执行一个sync命令,就是把内核的缓存存储到设备上。op自定O_SYNC 相当于调用fsync方  法,
                 O_DSYNC相当于调用fdatasync
方法。该方法也不会阻塞,会通过sigevent通知。
     int aio_error(const struct aiocb*aiocbp);
                 该函数返回当前aiocb的状态,EINPROCESS 表示正在执行,ECANCELED表示该操作被取消了。0表示该执行成功完成,如果该操作失败
                 会返回其它的正值。和errno中存储的值是一样的。
     ssize_t aio_return(struct aiocb* aiocb);
                  该函数返回该操作的最终状态。该操作应该只调用一次,并且实在调用aio_error之后返回值是除了EPROCESS的值。如果操作未完成该操作
                  的结果为定义。
     int aio_suspend(const struct aiocb* const aiocb_list[],  int nitems, const struct timespec *timeout);
                   该函数暂停调用的线程直到aiocb_list中有完成的项,或者是有信号到来,或者是timeout非NULL,并且指定的时间过去了。
     int aio_cancel(int fd, struct aiocb* aiocbp);
                   该函数尝试取消在fd指定的文件上面的正字啊排队未操作的aio操作,如果aiocbp是NULL,所有的这样的操作将被取消,如果aiocbp指定
                  了aio操作,则指定的操作被取消。
    int lio_listio(int mode, struct aiocb* const aiocb_list[], int nitems, struct sigevents* sevp);
                  批量开始操作,该操作开始aiocb_list指定的所有aio。mode可以指定两种模式 LIO_WAIT 堵塞到所有aio都完成, LIO_NOWAIT,异步模式,
                  该操作只是把aio操作加入到队列中。操作的完成由sigevent指定。操作的类型由aiocb结构的aio_li_opcode指定。

综述:

      开始的时候把aiocb结构初始化为0是个很好的变成习惯,在aio执行的时候,aio_buf是不能被改变的,使用同一个aiocb结构,同时执行都活着写操作是为定义的。
      目前的LINUX posix AIO 是通过glibc在用户空间提供的,这样会有一些局限,例如维护多线程执行io操作是昂贵的和可扩展性差的。目前基于内核的状态机的实现正在进行中(例如io_submit, io_setup, io_cancel, io_destroy,io_getevent),但是这写实现并不成熟。

附录:

sigevent:
        sigevent是同步程序的通知的一种结构。他包括一下两个结构体。
        union sigval{                                        //通过通知方式传递的数据
                   int sival_int;
                   void *sival_ptr;
       };
       struct sigevent{
             int sigev_notify;                                //通知方法
             int sigev_signo;                                 //通知信号
            union sigval sigev_value;                   //通知传递的数据
            void (*sigev_notify_function)(union sigval); //线程通知的函数体。
            void  * sigev_notify_attribute;                       //线程通知的属性
            pit_t    sigev_notify_thread_id;                       //thread id
};
  其中:sigev_notify 表示如何执行通知。他包含一下值:
   SIGEV_NONE :不会做任何事情。
   SIGEV_SIGNAL: 通过向进程发送sigev_signo指定的信号的方式来通知。通过sigaction注册的时候,如果指定了SA_SIGINFO,会把sigev_signo和sigev_value传递。
   SIGEV_THREAD  指定这个标志的时候,会像另起一个线程一样,执行sigev_notify_function指定的方法。sigev_notify_attribute指定该线程的属性。
  SIGEV_THREAD_ID 只用在timer。

阅读(655) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~