内核aio_linux内核aio功能
我正在测试内核异步io函数(不是posix
aio),并试图弄清楚它是如何工作的。下面的代码是一个完整的程序,其中我简单地将一个数组重复写入使用O_DIRECT打开的文件中。我在回调函数中收到一个错误“写错的字节期望1024得到0”(请参阅work_done()中的fprintf语句)。
对于不熟悉内核aio的用户,以下代码将执行以下操作:
初始化一些结构
准备AIO(io_prep_pwrite)
提交io请求(io_submit)
检查事件完成(io_getevents)
调用回调函数以查看是否一切正常。
我在步骤5遇到错误。如果不使用O_DIRECT打开文件,一切正常,但它超出了进行异步写入的目的。有人可以告诉我我在做什么错吗?这是内核aio的正确用法吗,例如,我对回调的使用正确吗?O_DIRECT的使用是否受到限制?
我使用’gcc -Wall test.c -laio’进行编译
提前致谢。
/*
* File: myaiocp.c
* Author: kmehta
*
* Created on July 11, 2011, 12:50 PM
*
*
* Testing kernel aio.
* Program creates a 2D matrix and writes it multiple times to create a file of desired size.
* Writes are performed using kernel aio functions (io_prep_pwrite, io_submit, etc.)
*/
#define _GNU_SOURCE
#define _XOPEN_SOURCE 600
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
char ** buf;
long seg_size;
int seg_rows;
double total_size;
char * filename;
static int wait_count = 0;
void io_task();
void cleanup();
void allocate_2D_matrix(int[]);
int file_open(char *);
void wr_done(io_context_t ctx, struct iocb* iocb, long res, long res2);
int main(int argc, char **argv) {
total_size = 1048576; //1MB
seg_size = 1024; //1kB
seg_rows = 1024;
filename = "aio.out";
int dims[] = {seg_rows, seg_size};
allocate_2D_matrix(dims); //Creates 2D matrix
io_task();
cleanup();
return 0;
}
/*
* Create a 2D matrix
*/
void allocate_2D_matrix(int dims[2]) {
int i;
char *data;
//create the matrix
data = (char *) calloc(1, dims[0] * dims[1] * sizeof (char));
if (data == NULL) {
printf("\nCould not allocate memory for matrix.\n");
exit(1);
}
buf = (char **) malloc(dims[0] * sizeof (char *));
if (buf == NULL) {
printf("\nCould not allocate memory for matrix.\n");
exit(1);
}
for (i = 0; i < dims[0]; i++) {
buf[i] = &(data[i * dims[1]]);
}
}
static void io_error(const char *func, int rc)
{
if (rc == -ENOSYS)
fprintf(stderr, "AIO not in this kernel\n");
else if (rc < 0)
fprintf(stderr, "%s: %s\n", func, strerror(-rc));
else
fprintf(stderr, "%s: error %d\n", func, rc);
exit(1);
}
/*
* Callback function
*/
static void work_done(io_context_t ctx, struct iocb *iocb, long res, long res2)
{
if (res2 != 0) {
io_error("aio write", res2);
}
if (res != iocb->u.c.nbytes) {
fprintf(stderr, "write missed bytes expect %lu got %ld\n",
iocb->u.c.nbytes, res2);
exit(1);
}
wait_count --;
printf("%d ", wait_count);
}
/*
* Wait routine. Get events and call the callback function work_done()
*/
int io_wait_run(io_context_t ctx, long iter)
{
struct io_event events[iter];
struct io_event *ep;
int ret, n;
/*
* get up to aio_maxio events at a time.
*/
ret = n = io_getevents(ctx, iter, iter, events, NULL);
printf("got %d events\n", n);
/*
* Call the callback functions for each event.
*/
for (ep = events ; n-- > 0 ; ep++) {
io_callback_t cb = (io_callback_t)ep->data ; struct iocb *iocb = ep->obj ; cb(ctx, iocb, ep->res, ep->res2);
}
return ret;
}
void io_task() {
long offset = 0;
int bufIndex = 0;
//Open file
int fd = file_open(filename);
//Initialize structures
long i;
long iter = total_size / seg_size; //No. of iterations to reach desired file size (total_size)
io_context_t myctx;
if(0 != io_queue_init(iter, &myctx))
{
perror("Could not initialize io queue");
exit(EXIT_FAILURE);
}
struct iocb * ioq[iter];
//loop through iter times to reach desired file size
for (i = 0; i < iter; i++) {
struct iocb *io = (struct iocb*) malloc(sizeof (struct iocb));
io_prep_pwrite(io, fd, buf[bufIndex], seg_size, offset);
io_set_callback(io, work_done);
ioq[i] = io;
offset += seg_size;
bufIndex ++;
if (bufIndex > seg_rows - 1) //If entire matrix written, start again from index 0
bufIndex = 0;
}
printf("done preparing. Now submitting..\n");
if(iter != io_submit(myctx, iter, ioq))
{
perror("Failure on submit");
exit(EXIT_FAILURE);
}
printf("now awaiting completion..\n");
wait_count = iter;
int res;
while (wait_count) {
res = io_wait_run(myctx, iter);
if (res < 0)
io_error("io_wait_run", res);
}
close(fd);
}
void cleanup() {
free(buf[0]);
free(buf);
}
int file_open(char *filename) {
int fd;
if (-1 == (fd = open(filename, O_DIRECT | O_CREAT | O_WRONLY | O_TRUNC, 0666))) {
printf("\nError opening file. \n");
exit(-1);
}
return fd;
}
内核aio_linux内核aio功能相关推荐
- linux aio参数,linux内核aio功能
我正在测试内核异步io函数(而不是posix aio),并试图弄清楚它是如何工作的.下面的代码是一个完整的程序,我只需将一个数组重复写入使用O_DIRECT打开的文件.我在回调函数"writ ...
- linux内核earlyprink,内核启动参数机制学习笔记
前两天把内核关于内核启动参数的一些知识彻底地分析了一遍<Linux内核源码分析--内核启动命令行的传递过程(Linux-3.0 ARMv7)>,发现了一些以前没有注意的细节问题,这里总结如 ...
- linux 为什么编译内核,Linux内核编译与安装
导读 Linux内核是一个用C语言写成的,符合POSIX标准的类Unix操作系统,内核是操作系统中最基本的一部分,提供了众多应用程序访问计算机硬件的机制.Linux内核的一大特点就是采用了整体式结构, ...
- 生效linux内核,Linux内核
内核 单内核体系设计.但充分借鉴了微内核设计体系的优点,为内核引入模块化机制. 内核组成部分: kernel:内核核心,一般为bzimage,通常在/boot目录下,名称为vmlinuz kernel ...
- [内核编程] 内核环境及其特殊性,驱动编程基础篇
[内核编程] 内核环境及其特殊性,驱动编程基础篇 在学习汉江独钓一书后,打算总结一下内核编程应该注意的事项,以及有关的一些基础知识.第一次接触内核编程,还真是很生疏,很多东西不能一下马上消化.这里做 ...
- linux 编译指cpu内核,linux内核编译与配置
linux是如何组成的? 答:linux是由用户空间和内核空间组成的 为什么要划分用户空间和内核空间? 答:有关CPU体系结构,各处理器可以有多种模式,而LInux这样的划分是考虑到系统的 安全性,比 ...
- Linux内核(5) - 内核学习的相关资源
"世界上最缺的不是金钱,而是资源."当我在一份报纸上看到这句大大标题时,我的第一反应是--作者一定是个自然环保主义者,然后我在羞愧得反省自身的同时油然生出一股对这样的无产主义理想者 ...
- Linux设备驱动开发详解-Note(5)---Linux 内核及内核编程(1)
Linux 内核及内核编程(1) 成于坚持,败于止步 Linux 2.6 内核的特点 Linux 2.6 相对于 Linux 2.4 有相当大的改进,主要体现在如下几个方面. 1.新的调度器 2.6 ...
- Linux设备驱动开发详解【三】_Linux 内核及内核编程
本文简介 由于 Linux 驱动编程本质属于 Linux 内核编程,因此有必要掌握 Linux 内核及内核编程的基础知识. 3.1-3.2 节讲解 Linux 内核的演变及 Linux ...
最新文章
- 2020-11-13size_t和int
- 手把手教你估算深度神经网络的最优学习率(附代码教程)
- 量子计算赛道上的巨头拉锯战
- wampserver使用过程中遇到的问题及相关配置
- [Swift]LeetCode781. 森林中的兔子 | Rabbits in Forest
- phpstorm的php函数文档插件
- 工作176:表单重置
- Java Web(五) JSP详解(四大作用域九大内置对象等)
- 计算机专业联考335分,联考专业分、文化分达到多少能过本科线(附2019年美术高考分数线汇总...
- 之江学院第0届 A qwb与支教 容斥与二分
- Hugo中文文档 快速开始
- Pure Pursuit纯跟踪算法Python/Matlab算法实现
- 颜值实力派—打造MySQL运行监控环境
- mysql 主键冲突 多个事务回滚_MySQL实战45讲Day38----自增主键不是连续的原因
- 如何查看Oracle数据库字符集 尚未研究
- 5.PSR-7: HTTP message interfaces
- 【语音合成】基于matlab线性预测系数和预测误差语音合成【含Matlab源码 564期】
- linux系统vmd软件如何使用,科学网—VMD (linux下分子可视化软件) - 刘雪静的博文...
- 由于CSDN博客广告太多,本博客暂时停止更新
- 西瓜书读书笔记(一)
热门文章
- 数据 3 分钟 | 国产数据库迎来 2 名开源玩家、数据库厂商年度报告都说了些什么?...
- 为什么预估执行计划与真实执行计划会有差异?
- 使用 scipy.fft 进行Fourier Transform:Python 信号处理
- 如何支撑企业快速构建数字孪生体
- 如何处理分析Flink作业反压的问题?
- MindSpore:基于本地差分隐私的 Bandit 算法
- Volcano 监控设计解读,一看就懂
- 小熊派开发实践丨漫谈LiteOS之传感器移植
- 【华为云技术分享】STM32L476移植华为LiteOS系列教程---Kconfig 6
- Flask使用bootstrap为HttpServer添加上传文件功能