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

news/2024/11/16 21:48:28/

01🙆‍♂️起因

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

/* 字符设备操作集 */
static struct file_operations gpio_fops={.owner      = THIS_MODULE,.open       = gpio_open,.release    = gpio_relase,.read       = gpio_read,.write      = gpio_write,.fasync     = gpio_fasync,.release    = gpio_release,
};

上面的结构体,

  1. 通过.open = gpio_open,的方式,进行初始化结构体的成员项。

  2. 将驱动注册到内核中。

  3. 然后,应用程序使用open 的时候,直接通过回调函数的形式来执行我们驱动实现的相关功能gpio_open

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 (*read_iter) (struct kiocb *, struct iov_iter *);ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);int (*iterate) (struct file *, struct dir_context *);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 (*mremap)(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 *);... // 省略};

02🙆‍♂️好处分析:

  1. 使用灵活,可以指定某一项进行初始化,而不是将所有的成员变量来初始化。
  2. 代码易于维护,内核中,会有大量的代码都会使用这个file_operations结构体来定义变量,并且初始化,如果结构体后续,需要添加成员,或者调整成员顺序,那么会引起大量的文件都要重新编译,牵一发而动全身。通过这种方式,就不用有这个但心。

03🙆‍♂️内存大小的变化

既然可以指定初始化结构体里面的几个变量,但结构体实例化后的内存是不是也会又变化?

答案是结构体变量,无论初始化与否,成员变量都会占用内存空间的。

测试代码如下:

#include "stdio.h"struct student{char name[20];int age;int height;
};int main(void)
{struct student stu1={ "01", 20, 178 };printf("%s:%d:%d\r\n", stu1.name, stu1.age, stu1.height);printf("stu1 size: %d\r\n", sizeof(stu1));struct student stu2={.name = "02",.age  = 28};printf("%s: %d\r\n",stu2.name,stu2.age);printf("stu2 size: %d\r\n", sizeof(stu2));return 0;
}

student结构体应该占据20+4+4个字节bytes的空间,实测如下

01:20:178    
stu1 size: 28 # 初始化三个成员变量
02: 28       
stu2 size: 28 # 初始化两个成员变量*  Press any key to close the terminal. 

http://www.ppmy.cn/news/60653.html

相关文章

【单目标优化算法】海鸥优化算法(Matlab代码实现)

💥 💥 💞 💞 欢迎来到本博客 ❤️ ❤️ 💥 💥 🏆 博主优势: 🌞 🌞 🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 …

数据埋点2

文章目录 1 数据埋点流程2 六个步骤实现数据埋点设计2.1 确认事件与变量2.2 明确事件的触发时机2.3 明确事件的上报机制2.4 设计数据表结构2.5 统一字段命名规范2.6 明确优先级 3 以电商购物成交转化为例实现数据埋点设计 作为数据分析师的你,是否和我一样经常会被业…

OI 数论模板总结

1.欧几里得算法 可以通过欧几里得算法求出最大公因子。 int gcd(int x, int y) //欧几里得算法 { return y0 ? x : gcd(y, x%y); }2.扩展欧几里得 可以通过扩展欧几里得求出 a x b y d axbyd axbyd 不定方程的一组整数解。( a , b , d a, b, d a,b,d为正整…

【热门框架】Mybatis-Plus入门介绍看这一篇文章就足够了

MyBatis-Plus 是在 MyBatis 的基础上进行了封装,提供了更加便捷的开发方式,具有简化开发、提高效率等优点。以下是 MyBatis-Plus 的一些特点和用法: 通用 CRUD 操作:MyBatis-Plus 提供了通用的 CRUD 接口,可以直接调用…

TinyJAMBU的制动原理——一种轻量化的认证密码

关于TinyJAMBU的定义和介绍在另一篇博文已经介绍过了,这里只对其动作原理进行描述和说明。 对应的博文链接如下:TinyJAMBU:一种轻量化密码介绍 首先,该密码是一个流密码体系的块密码框架。其加密模式整体上来看是块密码&#xff0…

Python 扩展教程(1): 调用百度AI

关于AI 自有计算机以来,人们就想让计算机具有人的感知、意识、概念、思维、行为,代替人的工作。AI (Artificial Interligence)是计算机科学的一个分支,专注研究、开发、模拟、扩展人的智能的理论、方法、技术及应用。 从研究领域和方法上&…

当音乐遇上Python:用Pydub自动分割音频

🎵 🎵 🎵 当音乐遇上Python:用Pydub自动分割音频 随着短视频应用的普及,越来越多人开始了解并尝试制作自己的短视频作品。而在制作短视频时,背景音乐的选择和使用也是非常重要的一步。很多人喜欢选择一首长…

JAVA编程语言中的关键字有哪些?

JAVA编程语言中有关键字,它们在编程中有着特定的含义和用途。下面是这些关键字的详细介绍: abstract: 抽象类或抽象方法的修饰符,用于表示方法或类是抽象的,不能被直接实例化。 assert: 断言关键字,用于在代码中进行条…