全部博文(2759)
分类: LINUX
2013-10-09 12:07:35
aio: POSIX 异步IO 。
aio接口允许应用程序同时运行一个或者多个IO操作(例如在后台)。应用程序可以选择不同IO完成的通知方式:通过信号,线程的实例化,
或者不需要通知。
aio包括一个结构体:
#include
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。