linux 内核io操作,关于Linux内核中的异步IO的使用

我们都知道异步IO的作用,就是可以提高我们程序的并发能力,尤其在网络模型中。在linux中有aio的一系列异步IO的函数接口,但是这类函数都是glibc库中的函数,是基于多线程实现,不是真正的异步IO,在内核中有真正的异步IO函数接口。下边我们来学习一下linux内核中的异步IO。

首先我们来看一下内核中异步IO的主要函数接口:

int io_setup(unsigned nr_events, aio_context_t *ctxp);

功能:用来初始化异步IO的上下文。

其中参数ctxp用来描述异步IO上下文, 参数nr_events表示小可处理的异步IO事件的个数。

int io_submit(io_context_t ctx, long nr, struct iocb *iocbs[]);

功能:提交初始化好的异步读写事件。

其中ctx是上文的描述句柄, nr表示提交的异步事件个数。Iocbs是异步事件的结构体。

int io_getevents(io_context_t ctx, long nr, struct io_event *events[], struct timespec *timeout);

功能:获得已经完成的异步IO事件。

其中参数ctx是上下文的句柄,nr 表示期望获得异步IO事件个数,events用来存放已经完成的异步事件的数据,timeout为超时事件。

int io_destroy(aio_context_t ctx);

功能:用于销毁异步IO事件句柄。

但是内核的异步IO通常和epoll等IO多路复用配合使用来完成一些异步事件,那么就需要使用epoll来监听一个可以通知异步IO完成的描述符,那么就需要使用eventfd函数来获得一个这样的描述符。

下边附上一个epoll和内核异步IO配合使用的示例代码:

#define TEST_FILE "aio_test_file"

#define TEST_FILE_SIZE (127 * 1024)

#define NUM_EVENTS 128

#define ALIGN_SIZE 512

#define RD_WR_SIZE 1024

struct custom_iocb

{

struct iocb iocb;

int nth_request;

};

//异步IO的回调函数

void aio_callback(io_context_t ctx, struct iocb *iocb, long res, long res2)

{

struct custom_iocb *iocbp = (struct custom_iocb *)iocb;

printf("nth_request: %d, request_type: %s, offset: %lld, length: %lu, res: %ld, res2: %ld\n", iocbp->nth_request, (iocb->aio_lio_opcode == IO_CMD_PREAD) ? "READ" : "WRITE",iocb->u.c.offset, iocb->u.c.nbytes, res, res2);

}

int main(int argc, char *argv[])

{

int efd, fd, epfd;

io_context_t ctx;

struct timespec tms;

struct io_event events[NUM_EVENTS];

struct custom_iocb iocbs[NUM_EVENTS];

struct iocb *iocbps[NUM_EVENTS];

struct custom_iocb *iocbp;

int i, j, r;

void *buf;

struct epoll_event epevent;

//创建用于获取异步事件的通知描述符

efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);

if (efd == -1) {

perror("eventfd");

return 2;

}

fd = open(TEST_FILE, O_RDWR | O_CREAT | O_DIRECT , 0644);

if (fd == -1) {

perror("open");

return 3;

}

ftruncate(fd, TEST_FILE_SIZE);

ctx = 0;

//创建异步IO的句柄

if (io_setup(8192, &ctx)) {

perror("io_setup");

return 4;

}

//申请空间

if (posix_memalign(&buf, ALIGN_SIZE, RD_WR_SIZE)) {

perror("posix_memalign");

return 5;

}

printf("buf: %p\n", buf);

for (i = 0, iocbp = iocbs; i < NUM_EVENTS; ++i, ++iocbp) {

iocbps[i] = &iocbp->iocb;

//设置异步IO读事件

io_prep_pread(&iocbp->iocb, fd, buf, RD_WR_SIZE, i * RD_WR_SIZE);

//关联通知描述符

io_set_eventfd(&iocbp->iocb, efd);

//设置回调函数

io_set_callback(&iocbp->iocb, aio_callback);

iocbp->nth_request = i + 1;

}

//提交异步IO事件

if (io_submit(ctx, NUM_EVENTS, iocbps) != NUM_EVENTS) {

perror("io_submit");

return 6;

}

epfd = epoll_create(1);

if (epfd == -1) {

perror("epoll_create");

return 7;

}

epevent.events = EPOLLIN | EPOLLET;

epevent.data.ptr = NULL;

if (epoll_ctl(epfd, EPOLL_CTL_ADD, efd, &epevent)) {

perror("epoll_ctl");

return 8;

}

i = 0;

while (i < NUM_EVENTS) {

uint64_t finished_aio;

//监听通知描述符

if (epoll_wait(epfd, &epevent, 1, -1) != 1) {

perror("epoll_wait");

return 9;

}

//读取完成的异步IO事件个数

if (read(efd, &finished_aio, sizeof(finished_aio)) != sizeof(finished_aio)) {

perror("read");

return 10;

}

printf("finished io number: %"PRIu64"\n", finished_aio);

while (finished_aio > 0) {

tms.tv_sec = 0;

tms.tv_nsec = 0;

//获取完成的异步IO事件

r = io_getevents(ctx, 1, NUM_EVENTS, events, &tms);

if (r > 0) {

for (j = 0; j < r; ++j) {

//调用回调函数

//events[j].data的数据和设置的iocb结构体中的data数据是一致。

((io_callback_t)(events[j].data))(ctx, events[j].obj, events[j].res, events[j].res2);

}

i += r;

finished_aio -= r;

}

}

}

close(epfd);

free(buf);

io_destroy(ctx);

close(fd);

close(efd);

remove(TEST_FILE);

return 0;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/551970.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux内核模块实验,linux内核模块实验(2学时).doc

第一个内核模块实验一&#xff1a; 预习要求&#xff1a;( 1 ) 做本实验之前&#xff0c;请复习相关内核模块知识。( 2 ) 请了解内核模块的编写、编译及安装与卸载方法。( 3 ) 请学习内核打印函数 printk() 的用法。( 4 ) 请复习 Makefile 文件的编写。二&#xff1a;实验目的&…

mobi格式电子书_进阶能力 | 了解常见的电子书格式

静读君是初中开始接触电子书的&#xff0c;那个时候以为电子书就是TXT&#xff0c;到后来渐渐地接触到了PDF、DOC、CAJ 才知道原来电子书还分这么多的格式&#xff0c;那个时候还在想&#xff0c;为什么要弄这么多不同的格式呢&#xff1f;那不是自找麻烦吗&#xff1f;接触的…

python的pass在函数中的作用_Pass Share:Python / Julia 中函数变量的传递机制

从 C / MATLAB 过来的同学注意&#xff01;Julia / Python 中使用的参数传递变量方式是不一样的。(以C的眼光看)在语法上细微的差别就会产生完全不一样的内容。(至少我被坑了很多次)。这篇文章的主要作用是逃坑以及方便各种从不同语言过来的人投奔我们Julia&#xff01;/狗头变…

linux启动keepalived服务,llinux企业常用服务---HA+keepalived双机热备

部署前准备&#xff1a;iptables和selinux没配置&#xff0c;关掉挂载系统镜像作为本地yum源&#xff0c;修改yum文件源码包准备keepalived-1.2.13.tar.gz环境介绍&#xff1a;2台centos6.5虚拟机&#xff0c;主服务器ip&#xff1a;192.168.100.150&#xff1b;从服务器ip&…

python 日志不会按照日期分割_python 按照日期切分大日志文件(重点)和按照指定大小切分日志文件...

#! /usr/bin/env python # -*- coding:utf8 -*- # 切分nginx 按照日期切分日志文件 from __future__ import division import os,sys big_file‘/data/logs/media.net.error.log‘ # 按照文件大小拆分 def split_by_filesize(fromfile,todir,chunksize0): """ c…

c++ udp通信_Web 通信协议,你还需要知道:SPDY 和 QUIC

一、开拓者&#xff1a;SPDY1. 简介&#xff1a;spdy 是由google推行的&#xff0c;改进版本的HTTP1.1 (那时候还没有HTTP2)。它基于TCP协议&#xff0c;在HTTP的基础上&#xff0c;结合HTTP1.X的多个痛点进行改进和升级的产物。它的出现使web的加载速度有极大的提高。HTTP2也借…

linux退出windows域,删除Windows AD域控制器的三种方法

一、域控可以正常工作1、删除辅助域控&#xff1a;单击“开始”&#xff0c;单击“运行”&#xff0c;然后键入以下命令&#xff1a;dcpromo /forceremoval然后按提示操作。2、删除主域控&#xff1a;1)打开Active Directory 用户和计算机 ->Domain Controllers,右键点击所要…

查看 rabbitmq 启动websocket 提示404_RabbitMQ 部署记录

erlang与rabbitmq版本对应关系&#xff1a;https://www.rabbitmq.com/which-erlang.html安装erlang下载地址&#xff1a;http://www.erlang.org/downloads11.安装依赖 2yum install -y gcc gcc-c ncurses ncurses-base ncurses-devel ncurses-libs ncurses-static ncurses-term…

react如何卸载组件_reactjs – 如何删除/卸载嵌套的反应组件

是的,你建议的解决方案render: function () {var home this.state.remove_home ? null : return ({home}),handleNavbarClick: function () {this.setState({remove_home: true});}或多或少是使用React处理此问题的“正确”方法.请记住,渲染的目的是描述组件在任何给定点上的…

linux远程windows执行cmd,Linux服务器远程连接window服务器并执行cmd命令

前段时间&#xff0c;要给一个分布式调度系统写一个运维脚本&#xff0c;这个分布式调度系统部分子系统部署在window服务器上&#xff0c;这个时候就要想办法用Linux远程来连接window服务器&#xff0c;并执行cmd命令。下面是我的解决方法&#xff1a;1、在Linux服务器上的处理…

python函数式编程读取数据时出现错误_Python编程中,函数遇到问题是抛出错误好还是约定返回值好?...

这其实是一个编码规范的问题&#xff0c;没有任何场景都适用的解决方案&#xff0c;就好比有了 list&#xff0c;但是还是需要 tuple&#xff0c;所以对于抛出异常好&#xff0c;还是返回值好&#xff0c;是需要具体情况看的。 在 C 语言中&#xff0c;通用的做法是函数返回一个…

access中如何画斜线_设计斜线表头

。1.4.16 在表格顶端加空行要在表格顶端加一个非表格的空白行&#xff0c;可以使用“CtrlShiftEnter”组合键通过拆分表格来完成。但当你的表格位于文档的最顶端时&#xff0c;有一个更为简捷的方法&#xff0c;就是先把插入点移到表格的第一行的第一个单元格的最前面&#xff…

Linux安装Flash脚本,Linux(CentOS)下的Shockwave Flash shell一键更新脚本

原创内容,转载请注明出处: https://www.myzhenai.com.cn/post/2318.html https://www.myzhenai.com/thread-17933-1-1.html关键字: Shockwave Flash一键更新脚本 Flash一键更新脚本这个脚本其实是我自己用的, 我的系统里安装了FlashPlayer软件和火狐(firefox)浏览器里安装了Sho…

收文处理和发文处理的环节_集气罩的设计是气体净化、废气处理系统设计的重要环节...

在工业生产中&#xff0c;常用于控制各种颗粒物和气态污染物的方法是将有害物质在发生源收集起来&#xff0c;经过净化设备净化后排到大气中&#xff0c;这就是局部排气净化系统&#xff0c;这种系统所需要的风量最小&#xff0c;效果好&#xff0c;能耗也少&#xff0c;是生产…

linux磁盘管理不用LVM,[linux] LVM磁盘管理(针对xfs和ext4不同文件系统)

简单来说就是&#xff1a;PV&#xff1a;是物理的磁盘分区VG&#xff1a;LVM中的物理的磁盘分区&#xff0c;也就是PV&#xff0c;必须加入VG&#xff0c;可以将VG理解为一个仓库或者是几个大的硬盘LV&#xff1a;也就是从VG中划分的逻辑分区如下图所示PV、VG、LV三者关系&…

cad监控图标_干货!多种不同环境的无线视频监控系统拓扑图

有人问&#xff0c;既然无线视频监控系统如此普及&#xff0c;是不是所有地方都能用到无线视频监控设备呢&#xff1f;例如在大街上、学校里&#xff0c;工厂中、写字楼内&#xff0c;建筑工地上、公园中、住宅小区里、江河岸边、港口码头、甚至是森林、戈壁滩等等。只要有需要…

linux qt手册,明远智睿I.MX6 Linux-4.1.15 QT5 程序编译手册

明远智睿I.MX6 Linux-4.1.15 QT5 程序编译手册[复制链接]编译主机环境编译主机CPU架构&#xff1a;64位编译主机系统&#xff1a;LinuxLinux发行版&#xff1a;UbuntuUbuntu版本号&#xff1a;14.04.5Ubuntu版本类型&#xff1a;桌面版Ubuntu系统类型&#xff1a;x86-64安装 SD…

axios 获取上传进度_PHP获取HTTP body内容的方法总结

有时候我们获取数据时需要根据Header中的格式来解析&#xff0c;比如上传一个json而不是一个文本。这里用到了 php输入|输出流 的概念。PHP 提供了一些杂项输入/输出(IO)流&#xff0c;允许访问 PHP 的输入输出流、标准输入输出和错误描述符&#xff0c; 内存中、磁盘备份的临时…

python编程快速上手 让繁琐工作自动化 豆瓣_2019年,这些豆瓣评分9.0以上的8本程序员好书你都知道吗?...

豆瓣这些9.0以上的高评分程序员好书你都知道有哪些吗&#xff1f;小编去豆瓣看了一下&#xff0c;推荐这8本最适用的程序员好书给你。 &#xff11;、UNIX环境高级编程&#xff08;第3版&#xff09;&#xff08;豆瓣评分&#xff19;.&#xff16;&#xff09;UNIX编程圣经 与…

hadoop集群swap_hadoop集群调优-OS和文件系统部分

OS and File System根据Dell(因为我们的硬件采用dell的方案)关于hadoop调优的相关说明&#xff0c;改变几个Linux的默认设置&#xff0c;Hadoop的性能能够增长大概15%。open file descriptors and files文件描述符是一个索引值&#xff0c;指向内核为每一个进程所维护的该进程打…