linux aio参数,Linux 异步 IO 之 Native AIO
Linux Native AIO
来看看 Linux 提供的 AIO 系统调用(自行封装的头文件 native_aio.h):
#ifndef __NATIVE_AIO_H__
#define __NATIVE_AIO_H__
#define _GNU_SOURCE
#include
#include
#include
#include
static inline int io_setup(unsigned nr_events, aio_context_t* ctx_idp)
{
return syscall(__NR_io_setup, nr_events, ctx_idp);
}
static inline int io_destroy(aio_context_t ctx)
{
return syscall(__NR_io_destroy, ctx);
}
static inline int io_submit(aio_context_t ctx, long nr, struct iocb** iocbpp)
{
return syscall(__NR_io_submit, ctx, nr, iocbpp);
}
static inline int io_getevents(aio_context_t ctx, long min_nr, long nr,
struct io_event* events, struct timespec* timeout)
{
return syscall(__NR_io_getevents, ctx, min_nr, nr, events, timeout);
}
static inline int io_cancel(aio_context_t ctx, struct iocb* iocb,
struct io_event* result)
{
return syscall(__NR_io_cancel, ctx, iocb, result);
}
#endif
通过 man 能够查到函数的描述,但是这些函数不是跨平台的,因此 libc 没有对这些函数进行封装,这里手动封装了一下。下面是一个使用示例:
#include "native_aio.h"
#include
#include
#include
#include
#include
#define NR_EVENT 1024
#define BUFSIZE 4096
int main(void)
{
int fd, ret = -1;
char* buf;
aio_context_t ctx;
struct io_event event;
struct iocb cb;
struct iocb* cblist[] = {&cb};
fd = open(__FILE__, O_RDONLY | O_DIRECT);
if (fd == -1) {
fprintf(stderr, "open(%s) failed: %s.\n", __FILE__, strerror(errno));
return -1;
}
buf = aligned_alloc(512, BUFSIZE);
if (!buf) {
fprintf(stderr, "aligned_alloc(%u) failed: %s.\n", BUFSIZE,
strerror(errno));
goto err1;
}
memset(&ctx, 0, sizeof(ctx));
ret = io_setup(NR_EVENT, &ctx);
if (ret != 0) {
fprintf(stderr, "io_setup failed: %s.\n", strerror(errno));
goto err2;
}
memset(&cb, 0, sizeof(cb));
cb.aio_data = (__u64)buf;
cb.aio_fildes = fd;
cb.aio_lio_opcode = IOCB_CMD_PREAD;
cb.aio_buf = (__u64)buf;
cb.aio_offset = 0;
cb.aio_nbytes = BUFSIZE;
ret = io_submit(ctx, 1, cblist);
if (ret != 1) {
fprintf(stderr, "io_submit failed: %s.\n", strerror(errno));
goto err3;
}
ret = io_getevents(ctx, 1, 1, &event, NULL);
if (ret != 1) {
fprintf(stderr, "io_getevents failed: %s.\n", strerror(errno));
goto err3;
}
if (event.res <= 0) {
fprintf(stderr, "io error: %s.\n", strerror(-(event.res)));
} else {
printf("read %lld byte(s):\n", event.res);
write(1, (const void*)(event.data), event.res);
}
err3:
io_destroy(ctx);
err2:
free(buf);
err1:
close(fd);
return ret;
}
程序首先打开一个只读文件,注意这里加了选项“O_DIRECT”,直接从磁盘读取文件。因为绕过了 page cache,所以一般程序都会自己来实现 cache;接着使用 aligned_alloc() 申请存放读取内容的 buffer,起始地址需要和磁盘逻辑块大小对齐(一般是 512 字节)。
准备工作完成后,调用 io_setup() 来初始化一个 aio_context_t 标识符,用于后续的 aio 操作。描述 aio 信息的主要是结构体 struct iocb(在 /usr/include/linux/aio_abi.h 中定义):
struct iocb {
/* these are internal to the kernel/libc. */
__u64 aio_data; /* data to be returned in event's data */
__u32 PADDED(aio_key, aio_reserved1);
/* the kernel sets aio_key to the req # */
/* common fields */
__u16 aio_lio_opcode; /* see IOCB_CMD_ above */
__s16 aio_reqprio;
__u32 aio_fildes;
__u64 aio_buf;
__u64 aio_nbytes;
__s64 aio_offset;
/* extra parameters */
__u64 aio_reserved2; /* TODO: use this for a (struct sigevent *) */
/* flags for the "struct iocb" */
__u32 aio_flags;
/*
* if the IOCB_FLAG_RESFD flag of "aio_flags" is set, this is an
* eventfd to signal AIO readiness to
*/
__u32 aio_resfd;
}; /* 64 bytes */
需要填充的字段包括:
aio_data:事件完成后随着 struct io_event 返回的内容,后面详细介绍;
aio_lio_opcode:IO 类型,可能包含以下取值:
IOCB_CMD_PREAD:对应系统调用 pread(),读取从指定位置开始的指定长度的内容,但是不改变文件偏移;
IOCB_CMD_PWRITE:对应系统调用 pwrite(),从指定位置写入指定长度的内容,但是不改变文件偏移;
IOCB_CMD_FSYNC:对应系统调用 fsync(),将元数据和文件内容写到磁盘;
IOCB_CMD_FDSYNC:对应 fdatasync(),将文件内容和必需的元数据写到磁盘;
IOCB_CMD_NOOP:不确定,据说还没被使用;
IOCB_CMD_PREADV:对应 preadv(),从当前位置读取指定数量和长度的 buffer,但不改变文件偏移;
IOCB_CMD_PWRITEV:对应 pwritev(),从当前位置写入指定数量和长度的 buffer,但不改变文件偏移。
aio_fildes:要操作的文件描述符;
aio_buf:要操作的 buffer 起始地址;
aio_nbytes:要读写的长度;
aio_offset:要读写的起始位置。
其它字段一定要置 0。
填充完成后就可以调用 io_submit() 提交请求了,请求提交后 io_submit() 会立即返回。接着可以调用 io_getevents() 获取在 aio_context_t 上提交的事件,函数的第二个参数是最少需要获取多少个事件,第三个参数是最多获取多少个事件,第四个参数是超时设置,如果超过指定事件还没等到最少个数的事件就返回,返回值就是实际返回的事件个数。
从 io_getevents() 返回后从 struct io_event 获取事件执行的结果:
struct io_event {
__u64 data; /* the data field from the iocb */
__u64 obj; /* what iocb this event came from */
__s64 res; /* result code for this event */
__s64 res2; /* secondary result */
};
其中的 data 字段就是 struct iocb 里的 aio_data;obj 就是 iocb 本身;res 小于等于 0 表示出错,-res 的值就是 errno,res 大于 0 表示读写成功的字节数;res2 不知道干啥用的。
最后用 io_destroy() 释放资源。
参考资料
linux aio参数,Linux 异步 IO 之 Native AIO相关推荐
- linux 内核io操作,关于Linux内核中的异步IO的使用
我们都知道异步IO的作用,就是可以提高我们程序的并发能力,尤其在网络模型中.在linux中有aio的一系列异步IO的函数接口,但是这类函数都是glibc库中的函数,是基于多线程实现,不是真正的异步IO ...
- linux aio参数,LINUX AIO
从Oracle9iR2开始支持Linux上的异步IO,但是Oracle9iR2和Oracle10gR1中的AIO模块默认是disable的,如果要启用必须relink一下 cd $ORACLE_HOM ...
- linux aio参数,linux内核aio功能
我正在测试内核异步io函数(而不是posix aio),并试图弄清楚它是如何工作的.下面的代码是一个完整的程序,我只需将一个数组重复写入使用O_DIRECT打开的文件.我在回调函数"writ ...
- linux 启动 参数,Linux启动参数
Linux启动参数 发布时间:2008-09-03 15:46:31来源:红联作者:Sednol linux noapic (跳过硬件检测) linux pci=noapic (跳过PCI卡部分硬件检 ...
- Linux系统Posix异步IO接口(aio.h):aio_read,aio_write,aio_error
目录 aio_read.c aio_write.c aio_suspend.c lio_listio.c 相关文章 aio_read.c #include<stdio.h> #includ ...
- linux操作系统之全局异步IO及可重入/不可重入函数
(1)全局变量异步I/O实现父子进程交替数数 1)信号捕捉函数 2)main函数实现信号交替 3)程序实现 1>创建子进程,父进程等待1s,等待子进程完成捕捉函数注册(捕捉信号SIGUSR1). ...
- linux getline参数,Linux下的getline函数
最近在做国嵌的mp3项目,在mp3主控程序中用到了这个函数,挺好使的,在这里记录一下.注意是linux下的,不是C++中的. 函数原型 ssize_t getline(char **lineptr, ...
- linux fg 参数,Linux的bg和fg命令简单介绍
我们都知道,在 Windows 上面,我们要么让一个程序作为服务在后台一直运行,要么停止这个服务.而不能让程序在前台后台之间切换.而 Linux 提供了 fg 和 bg 命令,让我们轻松调度正在运行的 ...
- linux方法参数,Linux的sysctl 命令 参数
Linux内核通过/proc虚拟文件系统向用户导出内核信息,用户也可以通过/proc文件系统或通过sysctl命令动态配置内核.比如,如果我们想启动NAT,除了加载模块.配置防火墙外,还需要启动内核转 ...
最新文章
- c++矩阵转置_C语言:数据结构-稀疏矩阵的压缩存储
- 10 个十分难得的 javascript 开发经验
- 八、Pandas的基本使用
- git 创建webpack项目_webpack项目的搭建及环境构建
- 虚拟机VMware Workstation安装Linux服务器Debian11系统详细教程
- 读梁宁《一次失控引发的信任评估---我看胡紫薇事件》
- .NET采集数据,放入数据库总结
- 我有一张1996年版一元钱,值多少钱?
- 51Nod-1001 数组中和等于K的数对【排序+二分查找】
- 利用R语言ggplot2包制作金字塔图,展示人口结构数据
- 【Android驱动】屏和TP谁先休眠的问题
- 21届校招中获得12家公司offer的一些经验(包括6家银行信息科技岗offer)
- SSR、SSE、SST、判定系数(可决系数、拟合优度)的计算公式
- RuntimeError: mat1 and mat2 shapes cannot be multiplied (192x64 and 4x3)
- java纲要_幼儿园综合素质笔试大纲
- 【H5游戏】-整一个简单的解压小游戏【抽纸巾】
- C# Environment.StackTrace、StackFrame、Tirm的使用技巧
- PowerPoint如何找回隐藏的iSlide设计工具
- vba二维数组初始化_VBA二维数组的基础介绍
- windows重装 启动时找不到安装盘 装系统时有盘解决
热门文章
- 谷歌扩招又扩建,又一波招聘高峰要来了?
- IOS XCode 控制台打印中文方法
- 解决SecureCRT(linux远程访问工具)中中文乱码问题
- 测试适合什么颜色衣服的软件,形象顾问 | 超准的颜色测试!一语道破你最适合穿什么颜色的衣服!...
- 生物神经网络与机器学习的碰撞,Nature论文提出DNA试管网络识别手写数字
- 西北工业大学计算机学硕复试,分享:西北工业大学计算机考研复试经验_跨考网...
- linux和鸿蒙的区别和联系,华为鸿蒙与linux关系
- 句句名言,虽然是写给女生的,但是,男生也更应该看看。
- C:\Users\Kelly\AppData\Roaming\npm-cache\_logs\2019-03-24T08_17_24_284Z-debug.log
- python阿凡提麦子问题_第142期-阿凡提系列幽默笑话二十则