前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >POSIX AIO -- glibc 版本异步 IO 简介

POSIX AIO -- glibc 版本异步 IO 简介

作者头像
用户3147702
发布2022-06-27 12:32:33
8450
发布2022-06-27 12:32:33
举报
文章被收录于专栏:小脑斧科技博客

1. 概述

linux 中最常用的 IO 模型是同步 IO,在这个模型中,请求发出后应用程序会阻塞直到满足条件(阻塞 IO),或在不满足条件的情况下立即返回出错(非阻塞 IO),这样做的好处是程序在等待 IO 请求完成时不会占用 CPU。 POSIX 定义了异步 IO 应用程序接口(AIO API),linux 2.6 以上版本的内核也实现了内核级别的异步 IO 调用。 异步 IO 的基本思想是允许进程发起很多 IO 操作,而不用阻塞任何一个,也不用等待任何操作的完成,直到 IO 操作完成时,进程可以检索 IO 操作的结果。

linux 下主要有两套异步 IO,分别是 glibc 实现版本,和 linux 内核实现、libaio 封装的版本。

2. IO 模型简介

write、read 如果没有设置 O_NONBLOCK 标识则为同步阻塞式 IO,一旦 IO 发起,则进程一直等待直到操作完成。 设置了 O_NONBLOCK 标识后,write、read 成为非阻塞 IO,调用后如果资源可用则进行操作,并立即返回,如果资源不可用则直接返回出错,这样的情况下,程序通常需要进入忙等待状态,反复调用 IO 操作,直到正常返回。 以上两种 IO 模型虽然可以很好地完成单机的 IO 操作,但是对于并发的请求则无法实现。

对于并发的多个请求,可以使用 IO 复用模型,如 select、poll、epoll 等,但是进程必须阻塞直到操作完成。 如果需要进行并发、非阻塞的 IO 操作,比如 CPU 密集型应用及较慢的 IO 操作应用场景下,使用异步 IO 是一个很好地选择。

2.1. 同步阻塞式 IO 模型

2.2. 同步非阻塞 IO 模型

2.3. 异步 IO 模型

3. POSIX AIO — glibc 版本异步 IO 简介

glibc 版本异步 IO 主要包含以下接口(全部定义于 aio.h 中,调用时必须使用 POSIX 实时扩展库 librt):

glibc 版本异步 IO 调用接口

函数

功能

原型

aio_read

请求异步读操作

int aio_read(struct aiocb *aiocbp);

aio_write

请求异步写操作

int aio_write(struct aiocb *aiocbp);

aio_error

检查异步请求的状态

int aio_error(const struct aiocb *aiocbp);

aio_return

获得完成的异步请求的返回状态

ssize_t aio_return(struct aiocb *aiocbp);

aio_suspend

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

int aio_suspend(const struct aiocb const list[], int nent, const struct timespec timeout);

aio_cancel

取消异步 I/O 请求

int aio_cancel(int fildes, struct aiocb *aiocbp);

lio_listio

同时发起多个异步IO传输

int lio_listio( int mode, struct aiocb list[], int nent, struct sigevent sig );

3.1. aiocb 结构

上述函数用到了一个 struct aiocb 结构。 主要包含以下字段:

代码语言:javascript
复制
struct aiocb {
    int                aio_fildes;        // 要被读写的文件描述符
    volatile void    *aio_buf;        // 读写操作的内存 buffer
    __off64_t        aio_offset;        // 读写操作的文件偏移
    size_t            aio_nbytes;        // 需要读写的字节长度
    int                aio_reqprio;    // 请求优先级
    struct sigevent aio_sigevent;    // 异步操作完成后的信号或回调函数

    /* Internal fields */
    ...
};

上述结构中有一个 aio_sigevent 域,用于定义异步操作完成时通知信号或回调函数。

代码语言:javascript
复制
struct sigevent
{
    int                sigev_notify;                    // 响应类型
    int                sigev_signo;                    // 信号
    union sigval    sigev_value;                    // 信号传递的参数
    void (*sigev_notify_function)(union sigval);    // 回调函数
    pthread_attr_t    *sigev_notify_attributes;        // 线程回调
}

上述结构中用到了一个联合体 sigval:

代码语言:javascript
复制
typedef union sigval
{
    int        sival_int;
    void    *sival_ptr;
} sigval_t;

通常被称为“信号的 4 字节值”,制定了信号传递的参数。

4. 函数说明

4.1. aio_read、aio_write

代码语言:javascript
复制
int aio_read( struct aiocb *aiocbp );
int aio_write( struct aiocb *aiocbp );

调用成功返回 0,失败返回 -1 并设置 errno。

将请求添加到 request_queue。 通过参数 aiocbp 指向的结构可以设置文件描述符、文件偏移量、缓冲区及大小等属性,函数执行后立即返回。 对于 aio_write,如果设置了 O_APPEND,则文件偏移量属性会被忽略。

4.2. aio_error

代码语言:javascript
复制
int aio_error( struct aiocb *aiocbp );

用于查询请求的状态。 返回值如下:

aio_error 函数返回值

返回值

意义

EINPROGRESS

请求尚未完成

ECANCELLED

请求已经被用用程序取消

-1

调用出错,出错原因查看 errno

4.3. aio_return

代码语言:javascript
复制
ssize_t aio_return( struct aiocb *aiocbp );

获取异步 IO 返回值。 调用成功返回读写的字符数,出错返回 -1。

4.4. aio_suspend

代码语言:javascript
复制
int aio_suspend( const struct aiocb *const cblist[],
        int n,
        const struct timespec *timeout );

阻塞进程,直到列表中的某个异步请求完成。 cblist 中任何一个异步请求完成,函数都会返回 0,出错返回 -1。

4.5. aio_cancel

代码语言:javascript
复制
int aio_cancel( int fd, struct aiocb *aiocbp );

取消一个异步请求,第二个参数为 NULL 则取消所有该 fd 上的异步请求。 成功取消返回 AIO_CANCELED,请求已经完成则返回 AIO_NOTCANCELED。 在取消多个请求的情况下,如果至少有一个请求没有被取消,则返回 AIO_NOT_CANCELED,如果没有一个请求可以被取消,则返回 AIO_ALLDONE。

4.6. lio_listio

代码语言:javascript
复制
int lio_listio( int mode,
        struct aiocb *list[],
        int nent,
        struct sigevent *sig );

同时发起多个异步请求,可以很大程度上提高系统的性能。

mode 参数可选 LIO_WAIT 或 LIO_NOWAIT 来声明该函数是否阻塞。 nent 参数定义了 list 列表的最大元素个数。 list 列表中可以有值为 NULL 的请求,则该请求被忽略。 sigevent 的指针定义了在所有 IO 操作都完成时产生的信号或调用的回调函数。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小脑斧科技博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 概述
  • 2. IO 模型简介
    • 2.1. 同步阻塞式 IO 模型
      • 2.2. 同步非阻塞 IO 模型
        • 2.3. 异步 IO 模型
        • 3. POSIX AIO — glibc 版本异步 IO 简介
          • 3.1. aiocb 结构
          • 4. 函数说明
            • 4.1. aio_read、aio_write
              • 4.2. aio_error
                • 4.3. aio_return
                  • 4.4. aio_suspend
                    • 4.5. aio_cancel
                      • 4.6. lio_listio
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档