关于Linux内核中的异步IO的使用

news2024/11/26 12:20:21

我们都知道异步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;

}

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。(点击找小助理领取)

 

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

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

相关文章

生成无限制微信小程序码

生成无限制的微信小程序码&#xff0c;主要是通过后端请求微信的接口&#xff0c;然后微信会把小程序码返回来。 本文不讲详细的方法了&#xff0c;只讲其中的一些关键点&#xff0c;官方文档也附上去了&#xff0c;结合这些点看官方文档会比较方便。 方法&#xff1a; 获取…

_8LeetCode代码随想录算法训练营第八天-C++字符串

_8LeetCode代码随想录算法训练营第八天-C字符串 28.实现strStr()459.重复的字字符串 28.实现 strStr() KMP算法 什么是KMP 是由三位学者发明的&#xff1a;Knuth&#xff0c;Morris和Pratt&#xff0c;所以取了三位学者名字的首字母。 KMP有什么用 KMP主要应用在字符串匹…

SuperMap iClient3D for WebGL/Cesium端性能优化

目录 一、请求优化 1.1 多子域 1.1.1 scene.open()打开场景 1.1.2 加载地形 1.1.3 加载影像 1.1.4 加载S3M 1.1.5 加载MVT 1.2 批量请求 1.2.1 地形 1.2.2 影像 二、内存优化 2.1 根节点驻留内存 2.2 自动释放缓存 2.3 内存管理 三、图层优化 3.1 LOD 3.2 空间索引 3.3 控制图层…

企业文件泄漏防不胜防?安全防护3步走!

有一些管理者认为公司从未曾发生过数据泄密事件而心存侥幸&#xff0c;但数据泄密的代价&#xff0c;只需发生过一次&#xff0c;就足以给企业带来巨大的损害。 十四五规划中&#xff0c;“数据安全”和“网络安全”多次出现&#xff0c;加上《数据安全法》、《个人信息保护法》…

Linux下printf输出字符串的颜色

基本打印格式: printf("\033[字背景颜色;字体颜色m字符串\033[0m" ); printf("\033[41;32m字体背景是红色&#xff0c;字是绿色\033[0m\n"); 41是字背景颜色, 32是字体的颜色, 字体背景是红色&#xff0c;字是绿色是要输出的字符串. 后面的\033 ...\033[0m…

推荐系统毕业设计 协同过滤商品推荐系统设计与实现

文章目录1 简介2 常见推荐算法2.1 协同过滤2.2 分解矩阵2.3 聚类2.4 深度学习3 协同过滤原理4 系统设计4.1 示例代码(py)5 系统展示5.1 系统界面5.2 推荐效果6 最后1 简介 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里是学长的毕设系列文章&#xff01; &#x1f525…

redis持久化方案介绍

Redis有两种持久化方案&#xff1a;1. RDB持久化 2. AOF持久化 1 RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后&…

[附源码]Python计算机毕业设计高校实习管理平台系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

【自然语言处理】基于TextRank算法的文本摘要

基于TextRank算法的文本摘要文本摘要是自然语言处理&#xff08;NLP&#xff09;的应用之一&#xff0c;一定会对我们的生活产生巨大影响。随着数字媒体的发展和出版业的不断增长&#xff0c;谁还会有时间完整地浏览整篇文章、文档、书籍来决定它们是否有用呢&#xff1f; 利用…

数据结构C语言版 —— 链表增删改查实现(单链表+循环双向链表)

文章目录链表1. 链表的基本概念2. 无头非循环单链表实现1) 动态申请节点2) 打印链表元素3) 插入节点头插法尾插法在指定位置之前插入在指定位置之后插入4) 删除节点删除头部节点删除末尾节点删除指定位置之前的节点删除指定位置之后的节点删除指定位置的节点5) 查找元素6) 销毁…

【图像评价】无参考图像质量评价NIQE【含Matlab源码 681期】

⛄一、无参考图像质量评价NIQE简介 理论知识参考&#xff1a;通用型无参考图像质量评价算法综述 ⛄二、部分源代码 function [mu_prisparam cov_prisparam] estimatemodelparam(folderpath,… blocksizerow,blocksizecol,blockrowoverlap,blockcoloverlap,sh_th) % Input …

013 单词速记

converse adj.相反的&#xff0c;颠倒的 v.交谈 con(加强语气)vers&#xff08;转反转&#xff09;e->反转 n.conversation 谈话&#xff0c;对话 adv.conversely 相反的 controversy n.争端 contro(counter) 相反 vers 转 lead to ~ 导致争端 contraversial 有争议…

MySQL-内置函数

文章目录内置函数日期函数字符串函数数学函数其他函数内置函数 日期函数 current_date();current_time();current_timestamp(); 应用&#xff1a; 创建生日表 插入数据&#xff1a; 创建评论区 采用datetime 时间戳自动填充时间 查询两分钟之内发的帖子 评论时间2min…

C语言期末集训1(大一,超基础,小猫猫大课堂配套练习)——顺序结构和分支结构的题

更新不易&#xff0c;麻烦多多点赞&#xff0c;欢迎你的提问&#xff0c;感谢你的转发&#xff0c; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我…

安科瑞配电室环境监控系统解决方案-Susie 周

1、概述 配电室综合监控系统包括智能监控系统屏、通讯管理机、UPS电源、视频监控子系统&#xff08;云台球机、枪机&#xff09;、环境监测子系统&#xff08;温度、湿度、水浸、烟感&#xff09;、控制子系统&#xff08;灯光、空调、除湿机、风机、水泵&#xff09;、门禁监…

Redis分布式锁 - 基础实现及优化

应用场景 互联网秒杀抢优惠卷接口幂等性校验 代码示例 案例1 - StringRedisTemplate基础实现 package com.wangcp.redisson;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org…

以流量为王的时代,如何获得不错的流量,泰山众筹如何脱颖而出?

由于互联网、疫情等因素的影响&#xff0c;实体业务变得越来越困难。许多实体店已经开始转向在线电子商务&#xff0c;但运营一个好的电子商务平台并不容易。没有稳定的流量和忠实的用户&#xff0c;很难达到理想的效果。那到底如何才能获得不错的“流量”呢&#xff1f;泰山众…

第十四届蓝桥杯集训——JavaC组第十三篇——for循环

第十四届蓝桥杯集训——JavaC组第十三篇——for循环 目录 第十四届蓝桥杯集训——JavaC组第十三篇——for循环 for循环(重点) 倒序迭代器 for循环死循环 for循环示例 暴力循环 等差数列求和公式 基础循环展开 循环控制语句 break结束 continue继续 for循环(重点) f…

【图像融合】多尺度奇异值分解图像融合【含Matlab源码 2040期】

⛄一、多尺度奇异值分解的偏振图像融合去雾算法简介 立足于提高传统算法的适应性&#xff0c;提高去雾图像的质量&#xff0c;本文设计了如图 2 所示的去雾算法流程。首先&#xff0c;使用基于最小二乘方法计算出更加精确的偏振信息&#xff0c;改善了以往偏振信息计算不准确的…

基于Qt(C++)实现(PC)学生信息管理系统【100010043】

学生信息管理系统 一、系统指南 本系统为表格式的学生信息管理系统&#xff0c;提供了文件新建、打开及保存功能&#xff0c;还可在表格中对数据进行增加、删除、修改、搜索&#xff0c;下面将一一介绍这些功能 1、新建文件 新建文件将会产生一个全新的空表格&#xff0c;…