linux驱动---file_operations异步读写aio_read、aio_write

Linux中如何使用异步I/O 技术 本节将探索 Linux 的异步 I/O 模型,从而帮助我们理解如何在应用程序中使用这种技术。在传统的 I/O 模型中,有一个使用惟一句柄标识的 I/O 通道。在 UNIX® 中,这些句柄是文件描述符(这对等同于文件、管道、套接字等等)。在阻塞 I/O 中,我们发起了一次传输操作,当传输操作完成或发生错误时,系统调用就会返回。Linux 上的 AIOAIO 在 2.5 版本的内核中首次出现,现在已经是 2.6 版本的产品内核的一个标准特性了。在异步非阻塞 I/O 中,我们可以同时发起多个传输操作。 阅读详情

简述:
file_operations中read,write是同步读写,异步读写用接口是aio_read、aio_wirte(在4.5版本中发现已经把名字改成read_iter、write_iter)。

异步读写对应的系统调用API:

int aio_read(struct aiocb *__aiocbp);
int aio_write(struct aiocb *__aiocbp);

定义在头文件中(如ubuntu,/usr/include/aio.h):

#include <aio.h>

详细的关于异步读写应用程序编程,参考下面博客:
慢慢聊Linux AIO

场景考虑:
同步读写:应用程序发起读写后,等到读写函数完成返回,才能继续跑后面的代码。
异步读写:应用程序发起读写后,将读写注册到队列,然后立马返回,应用程序继续跑后面的代码,速度非常快,当读写动作完成后,系统发消息通知应用程序,然后应用程序接收读写结果。

根据场景选择,驱动可以同时都实现同步和异步的接口。

file_operations结构体定义(在include/linux/fs.h):

struct file_operations {
    struct module *owner;
    loff_t (*llseek) (struct file *, loff_t, int);
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    int (*readdir) (struct file *, void *, filldir_t);
    unsigned int (*poll) (struct file *, struct poll_table_struct *);
    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
    long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
    int (*mmap) (struct file *, struct vm_area_struct *);
    int (*open) (struct inode *, struct file *);
    int (*flush) (struct file *, fl_owner_t id);
    int (*release) (struct inode *, struct file *);
    int (*fsync) (struct file *, loff_t, loff_t, int datasync);
    int (*aio_fsync) (struct kiocb *, int datasync);
    int (*fasync) (int, struct file *, int);
    int (*lock) (struct file *, int, struct file_lock *);
    ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
    unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
    int (*check_flags)(int);
    int (*flock) (struct file *, int, struct file_lock *);
    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
    int (*setlease)(struct file *, long, struct file_lock **);
    long (*fallocate)(struct file *file, int mode, loff_t offset,
              loff_t len);
    int (*show_fdinfo)(struct seq_file *m, struct file *f);
};

其中异步读写:

ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

在linux 4.5版本中已经变成:

ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);

驱动如果已经实现了同步的读写,异步的实现还需要用到include/linux/aio.h中的数据结构和函数以及工作队列。
异步结构体struct kiocb;
函数:bool is_sync_kiocb(struct kiocb *kiocb),判断此处aio_read或aio_write是否指定为同步,是同步返回true,不是同步返回false。
函数:void aio_complete(struct kiocb *iocb, long res, long res2),通知系统异步完成,res为读取字节数,res2一般为0.

驱动接口实现例子:

struct kiocb *aki;
struct iovec *aiov;
loff_t aio_off = 0;
struct workqueue *aiowq;

void data_a(struct work_struct *work);
DECLARE_DELAYED_WORK(aio_delaywork,data_a);

ssize_t d_read(struct file *f, char __user *buf, size_t n, loff_t *off)
{
}
void data_a(struct work_struct *work)
{
    int ret = 0;
    ret = d_read(aki->ki_filp,aiov->iov->iov_base,n,&off);
    aio_complete(aki,ret ,0);
}
ssize_t d_aio_read(struct kiocb *ki, const struct iovec *iovs, unsigned long n, loff_t off)
{
    if(is_sync_kiocb(ki))
        return d_read(ki->ki_filp,iovs->iov->iov_base,n,&off);
    else
    {
        aki = ki;
        aiov = iovs;
        aio_off = off;
        queue_delayed_work(aiowq,aio_delaywork,100);
        return -EIOCBQUEUED;//一般都返回这个,
    }
}
void init_aio()
{
    aiowq= create_workqueue("aiowq");
}

新版本的用法如下:

ssize_t d_read_iter(struct kiocb *ki, struct iov_iter *iovs)
{
    if(is_sync_kiocb(ki))
        return d_read(ki->ki_filp,iovs->iov->iov_base,n,&off);
    else
    {
        aki = ki;
        aiov = iovs;
        aio_off = off;
        queue_delayed_work(aiowq,aio_delaywork,100);
        return -EIOCBQUEUED;
    }
}

这样,如果本次异步系统调用指定为同步,就和一般的read一样,如果是异步,就加入到一个workqueue,等到work(这个work,最好用延时版本)完成后,再通知系统。(个人理解,没有验证过- _ -,后面验证如发现不对再修改)
这样,应用程序(进程)可以很快返回,将读写的动作交给了workqueue的线程处理,完成后,再通知应用程序。
然后:

struct file_operations fop = {
.....
...
.aio_read = d_aio_read,
.....
...
};

就ok,异步写和读差不多用法。

异步读写,主要是在系统中差异,驱动只要实现对应的接口,类似同步的。

参考博客:
Linux驱动中的异步函数

linux内核file_operations的赋值流程跟踪 我们知道linux系统中文件有很多种,包括普通文件,目录文件,设备文件,管道文件,套接字文件等.文件在内核中用file结构体表示,file对象中有个重要成员 f_op指针,它指向file_operations,该结构体定义了一系列文件操作的函数指针集合,例如open,read,write,ioctl,mmap等.当对文件进行操作时,最终是调用对应的函数指针进行操作. linux中支持很多种文件系 阅读详情

相关推荐

Linux内核结构体“file_operations“ 初始化以及内存占用分析

在学习字符设备驱动的时候,看到Linux内核中的结构体的指定初始化方式(designated initializer)使用方式,之前没有见过这种初始化形式,做一点探索。

Dallas01的博客 1438

aio_read 函数这么好用,还用什么read干嘛?(两者区别)

函数确实提供了异步读取文件的能力,这在某些情况下是非常有用的,尤其是当应用程序需要同时处理多个I/O操作时。异步I/O操作可以在不阻塞主线程的情况下进行,从而提高了应用程序的响应性和效率。函数取决于你的具体需求和场景。如果你需要高性能的异步I/O操作,并且你的应用程序可以处理异步操作的复杂性和潜在的风险,那么。可能是一个不错的选择。然而,如果你只是需要简单地读取数据并且不需要复杂的异步操作,那么。函数可能是更合适的选择。

symsyq的博客 978

Multisim 14.0元件库下载权威指南:官方与社区资源

详解Multisim元件库下载的官方途径与可靠社区资源,帮助用户快速获取Multisim 14.0所需元件模型,提升电路仿真效率。

weixin_32925455的博客 754

如何用AIO技术提高程序性能

AIO 可以帮助你构建更有效地使用可用 CPU 资源的应用程序。 虽然这种 I/O 模型与大多数 Linux 应用程序中的传统阻塞模式不同,但异步通知模型在概念上很简单,还可以简化你的设计。

lucasma的博客 1451

ThingsBoard入门实战(二):ThingsBoard 设备接入

文章目录ThingsBoard 设备接入一、设备配置/设备类型二、设备三、设备接入HTTPCOAPMQTT四、下一步 ThingsBoard 设备接入 设备接入并不一定需要真正的设备,我们可以通过程序。或者命令来模拟设备,向平台发送信息。 这节我们先为用户分配一个设备,然后通过模拟设备命令更新设备的状态(遥测值)。 一、设备配置/设备类型 添加一个叫"路灯"的设备配置。 设备配置听起来比较抽象,可以认为是设备类型或者是设备类型的配置。实际上,ThingsBoard 中很多时候让选择设备类型,就是选的这个。

AIGC搞起 1万+

Miniconda入门:在CentOS上的安装、基本操作、目录结构、卸载

Miniconda是一个 免费的 轻量级的 conda安装程序 它只包含conda、Python、pip、zlib等基础的文件和依赖包 使用conda install命令可从Anaconda存储库中安装额外的conda包 简介 下载 安装 基本操作 虚拟环境的操作 包的操作 目录结构 卸载

ArYe 1万+

linux 异步读写,linux驱动---file_operations异步读写aio_read、aio_write

简述:file_operations中read,write是同步读写,异步读写用接口是aio_read、aio_wirte(在4.5版本中发现已经把名字改为read_iter、write_iter)。html异步读写对应的系统调用API:nodeint aio_read(struct aiocb *__aiocbp);int aio_write(struct aiocb *__aiocbp);定义...

weixin_34668160的博客 1616

具身智能与空天具身智能:从理论到实践的AIBOX技术革命

本文深入探讨了具身智能从理论到实践的发展,重点介绍了AIBOX技术如何作为边缘智能计算模块,为无人机、机器人等无人系统提供可进化的“大脑”。文章通过空天具身智能等应用场景,阐述了AIBOX在实现感知、决策、行动一体化闭环中的核心作用,并展望了其在协同智能与规模化部署中的未来挑战与机遇。

lll78的博客 768

Linux内核4.1在file_operations的read_iter和write_iter

在中文网站里,对结构体file_operations的描述中仍大多停留在旧版本,包含 ssize_t (*aio_read)(struct kiocb * , char __user * buffer, size_t size , loff_t p); 可以看出,这个函数的第一、三个参数和本结构体中的read()函数的第一、三个参数是不同 的, 异步读写的第三个参数直接传递值,而同步读写的第三个参数传递的是指针,因为AIO从来不需要改变文件的位置。 异步读写的第一个参数为指向kiocb结...

qq_41386447的博客 4123

保姆级教程:用BMS的HVIL检测电路,手把手教你排查高压互锁故障(附PWM/直流源方案对比)

本文详细解析了BMS中的HVIL检测电路,通过对比直流源与PWM两种方案,提供了一套系统化的高压互锁故障诊断流程。从电路原理到实战技巧,帮助维修人员精准定位故障根源,提升电动汽车高压系统的安全性和可靠性。

weixin_29300241的博客 392

Claude AI实战指南:从注册到精通,突破手机验证的终极解决方案

本文提供了一份详尽的Claude AI实战指南,重点解决了国内用户注册过程中的手机号验证难题,并分享了使用技巧。文章详细介绍了如何通过虚拟手机号服务等方案完成注册,并深入解析了Opus、Sonnet、Haiku三大模型的特点与选择策略,帮助用户从注册到精通,高效利用这一安全、健谈的AI助手进行内容创作、编程开发与学习研究。

weixin_29092031的博客 1233

Linux 字符设备驱动结构(四)—— file_operations 结构体知识解析

file_operations 结构体知识解析 file_operations 结构体中成员的解析

发如雪 3561

ADG同步性能优化:如何正确配置standby redolog避免WAIT_FOR_LOG状态

本文深入剖析了Oracle ADG(Active Data Guard)同步中常见的WAIT_FOR_LOG状态,指出其根源在于Standby Redo Log(SRL)配置不当。文章提供了从诊断到优化的完整实践指南,重点阐述了SRL大小匹配、组数充足等黄金配置法则,帮助架构师从根本上避免同步延迟,实现稳定高效的实时数据同步。

weixin_29200485的博客 335

Linux内核开发之异步通知与异步I/O(五)

“小王呢,今天开始讲AIO与设备驱动,这也是设备驱动通知与异步IO的最后一节了,下次咱们就要开始讲更高级的东西,比如中断啦,时钟等”   在Linux内核中,每个IO请求都对应一个kiocb结构体,其ki_filp成员指向对应的file指针,通过is_sync_kiocb可以判断某Kiocb时候为同步IO请求,如果非真,表示是异步IO请求。   块设备和网络设备本身就是异步的。只有字符设备驱动必须

数据挖掘及搜索专栏 491

C# WPF上位机实战:从零开发空压机监控系统(含实时监控+故障预警+数据追溯)

在工业生产场景中,空压机作为核心动力设备,常面临这些痛点:压力/温度异常导致停机、油耗超标未及时发现、设备故障追溯无数据支撑、人工巡检效率低且易遗漏。而基于C# WPF开发的空压机监控系统,能通过实时采集设备运行参数、智能分析运行状态、联动故障预警,实现“状态监控-异常告警-数据追溯-远程管控”全流程自动化,完美解决传统管理模式的弊端。今天就带大家落地这套空压机监控系统,基于C# + .NET 8 + WPF + Modbus TCP/RTU协议,整合压力、温度、油耗、运行时长等核心参数监控,搭配WPF的数

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1104

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【Linux】【file_operations】设备驱动中的file_operations详解

首先,我们需要定义设备号。// 自定义主设备号// 分配字符设备号// 初始化 cdev 和 file_operations// 注册字符设备// 创建设备类// 创建设备实例return 0;接下来,我们定义结构体,并实现读写函数。// 读取数据int ret;return 0;// 已经到达文件末尾return ret;// 写入数据// 设备打开时的操作return 0;// 设备关闭时的操作return 0;

极客代码 3180

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

linux驱动 struct file_operations 解析

目录 file_oprations整体解析 int (*open) (struct inode *, struct file *); int (*release) (struct inode *, struct file *); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*w...

shenlong1356的博客 1458

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Linux字符驱动设备file_operations结构体分析

原文地址:https://www.cnblogs.com/chen-farsight/p/6181341.html struct _file_operations struct_file_operations在kernel/include/fs.h这个文件里面被定义的,如下所示: struct file_operations {   struct module *owner;//拥有该结...

M2嵌入式 932

File_operations结构体

file_operation通俗解释

monkea123的博客 3738

[Linux]学习笔记系列 -- [fs]read_write

Linux文件读写VFS实现:read_write.c 摘要:fs/read_write.c是Linux内核VFS层的核心组件,提供统一的文件读写接口。它实现了POSIX标准的read/write系统调用,通过抽象层将请求分发给具体文件系统或设备驱动。该技术解决了操作系统统一I/O接口的关键问题,支持多种读写变体(如pread、readv等),成为所有用户空间I/O操作的基础入口。虽然稳定高效,但在高性能场景下存在系统调用开销和阻塞模型等局限,现代应用可选用mmap或io_uring等替代方案。作为Linu

wdfk-prog.space 1261

linux 内核 file_operations结构体各项解析

struct module *owner 第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针. 这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为 THIS_MODULE, 一个在 <linux/module.h> 中定义的宏. loff_t (*llseek) (struct file *...

whatday的专栏 1372

linux驱动 file_operations open返回值,file_operations中各项解析

linux设备驱动中file_operations结构体分析struct module *owner第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针. 这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为 THIS_MODULE, 一个在 中定义的宏.loff_t (*llseek) (struct file ...

weixin_29210727的博客 688

linux设备驱动中file_operations结…

linux设备驱动中file_operations结构体分析  struct module *owner 第 一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针. 这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为 THIS_MODULE, 一个在 中定义的宏. loff_t (*llseek) (stru

为了部落! 637

Linux中的File_operations结构体

struct module *owner  第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针.  这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为  THIS_MODULE, 一个在 &lt;linux/module.h&gt; 中定义的宏.这个宏比较复杂,在进行简单学习操作的时候,一般初始化为THIS_M...

weixin_38725917的博客 214
上一篇: linux驱动---file_operations之llseek
下一篇: linux驱动---file_operations之poll
eZiMu
博客等级 码龄10年 48粉丝 33原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值