博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unix环境变量--POSIX异步I/O
阅读量:2194 次
发布时间:2019-05-02

本文共 3013 字,大约阅读时间需要 10 分钟。

异步 I/O 是针对同步 I/O 提出的概念,它不需要线程等待 I/O 结果,而只需要请求进行传输,然后系统会自动完成 I/O 传输,结束或者出现错误时会产生相应的 I/O 信号,用户程序只需要设置好对应的信号陷入函数,即可处理一个异步 I/O 事件。

#include 
struct aiocb { int aio_fildes; /* 用户用来读或者写的文件描述符 */ off_t aio_offset; /* 开始读写的偏移量 */ volatile void *aio_buf; /* 用于读或写的缓冲区 */ size_t aio_nbytes; /* 操作的字符个数 */ int aio_reqprio; /* 操作的优先级,但不一定生效 */ struct sigevent aio_sigevent; /* 异步IO完成后,通知进程的方式,详细见下面 */ int aio_lio_opcode; /* Operation to be performed;lio_listio() only */ }; struct sigevent{ int sigev_notify; // 通知类型 int sigev_signo; // 信号值 union sigval sigev_value; // 回调函数的参数 void (*sigev_notify_function)(union sigval); // 回调函数 pthread_attr_t *sigev_notify_attributes; // };

                       sigev_notify的取值有以下三种:

                       SIGEV_NONE:异步I/O请求完成后,不通知进程

                       SIGEV_SIGNAL:异步I/O请求完成后,产生由sigev_signo字段指定的信号。如果应用程序已选择捕捉信号,且在建立信号处理程序的时候指定了SA_SIGINFO标志,那么该信号将被入队(如果实现支持排队信号),信号处理程序会传送给一个siginfo结构,该结构的si_value字段被设置为sigev_value

                       SIGEV_THREAD 当异步I/O请求完成后,由sigev_notify_function指定的函数被调用,sigev_value是唯一的参数。除非sigev_notify_attributes字段被设定为pthread属性结构的地址,且结构指定了另外的线程属性,否则该函数将在分离状态下的单独的线程下执行。

#include 
int aio_read(struct aiocb *aiocbp); int aio_write(struct aiocb *aiocbp); int aio_fsync(int op,struct aiocb *aiocbp); int aio_error(const struct aiocb *aiocbp); ssize_t aio_return(const struct aiocb *aiocbp); int aio_suspend(const struct aiocb *list,int nent,const struct timespec* timeout); int aio_cancel(int op,struct aiocb *aiocbp);

异步IO的操作流程大概如下:

(1)使用aio_read()或者aio_write()将操作请求放入到等待处理的队列中。这两个函数的返回值与实际操作结果并没有任何关系

(2)aio_fsync()函数用于将aio_write()的写请求同步到硬盘,op指定异步的方式,若op为O_DSYNC则表示只是更新硬盘文件内容,若op为O_SYNC则表示等待实际I/O结束才返回,从而确保修改过的块立即写到硬盘上。

(3)aio_error()是为了获取到一个异步读写或同步的状态,返回值有以下几种情况:

     0:异步操作完成,可以调用aio_return()函数获取操作返回值

     -1:aio_error函数调用失败

      EINPROGRESS:异步读写或同步仍未完成

 (4)如果aio_error()获取到异步操作已经完成,则可以使用函数aio_return()获取异步操作的返回值,此时必须确保异步读写或同步已经完成,函数调用失败返回-1.

 (5)如果在完成了所有事务之后,异步IO仍然没有完成,可以使用aio_suspend()阻塞进程,直到所有的操作完成,其中list是AIO控制块数组,nent表明了数组的个数。aio_suspend()的返回值有三种:(1)如果被信号中断,它将返回-1,并将errno设置为EINTR.(2)如果timeout超时,它将返回-1,并将errno设置为EAGAIN,timeout为NULL则表示不限时(3)如果返回值为0,则表示所有异步IO都已经完成,将不阻塞直接返回

(6)当我们不想等待异步IO的操作时,可以使用函数aio_cancel()来尝试取消他们。fd为操作的文件描述符,aiocbp为操作的数据块,如果aiocbp为NULL,则表示取消fd上面的所有异步IO操作。返回值有以下4种情况:

   AIO_ALLDONE:所有异步IO操作在尝试取消他们之前都已经完成

   AIO_CANCELED:所有要求的操作已被取消

   AIO_NOTCANCELED:至少一个操作请求没有被取消。

   -1:函数调用失败

 

还有一个函数,它既可以以同步接口调用,也可以以异步接口调用。

#include 
int aio_listio(int mode,struct aiocb* list,int nent,struct sigevent* sigev);

mode参数决定该函数是异步还是同步IO,如果该参数被设置为LIO_WAIT,则表示该函数是同步的,即在所有操作完成后,函数才返回,此时sigev将被忽略。如果被设置为LIO_NOWAIT,函数将是异步IO,即只是将访问请求放在队列中即返回,在所有IO结束后,按照sigev参数指定的方式被异步通知,如果不想被通知,可以将sigev设置为NULL。注意,每个控制块都有自己在完成后的通知方式,这里的sigev是另外附加的,它是是所有操作完成后,进行通知。

list是控制块的列表,nent表示个数。

 

转载地址:http://jwpub.baihongyu.com/

你可能感兴趣的文章
HTML中表格的使用
查看>>
(模板 重要)Tarjan算法解决LCA问题(PAT 1151 LCA in a Binary Tree)
查看>>
(PAT 1154) Vertex Coloring (图的广度优先遍历)
查看>>
(PAT 1115) Counting Nodes in a BST (二叉查找树-统计指定层元素个数)
查看>>
(PAT 1143) Lowest Common Ancestor (二叉查找树的LCA)
查看>>
(PAT 1061) Dating (字符串处理)
查看>>
(PAT 1118) Birds in Forest (并查集)
查看>>
数据结构 拓扑排序
查看>>
(PAT 1040) Longest Symmetric String (DP-最长回文子串)
查看>>
(PAT 1145) Hashing - Average Search Time (哈希表冲突处理)
查看>>
(1129) Recommendation System 排序
查看>>
PAT1090 Highest Price in Supply Chain 树DFS
查看>>
(PAT 1096) Consecutive Factors (质因子分解)
查看>>
(PAT 1019) General Palindromic Number (进制转换)
查看>>
(PAT 1073) Scientific Notation (字符串模拟题)
查看>>
(PAT 1080) Graduate Admission (排序)
查看>>
Play on Words UVA - 10129 (欧拉路径)
查看>>
mininet+floodlight搭建sdn环境并创建简答topo
查看>>
【linux】nohup和&的作用
查看>>
Set、WeakSet、Map以及WeakMap结构基本知识点
查看>>