Linux学习笔记(2)--一些内核接口
1)dump_stack
dump_stack()是Linux内核中的一个函数,用于在内核中输出当前的函数调用栈。该函数会输出当前线程(或进程)的函数调用栈信息,以及相应的调用地址和虚拟内存地址等信息,一般用于诊断程序运行时的错误或异常。使用该函数可以帮助开发者找到程序崩溃的原因所在,并进行快速排错。它常常被用于内核调试和性能分析。
2)kref_put
kref_put
是 Linux 内核中的一个函数,用于在引用计数器(也称为 kref)归零时释放内核资源。
具体来说,当内核中的某个结构体需要在多个地方被引用,通过使用 kref 引用计数器可以追踪该结构体被引用的数量。当该结构体不再被需要时,可以通过 kref_put
函数来将该结构体的引用计数减 1,如果此时引用计数为 0,则说明该结构体可以被安全地释放。
以下是 kref_put
函数的原型:
void kref_put(struct kref *kref, void (*release)(struct kref *kref));
其中,kref
是指向内核引用计数器的指针,release
是一个回调函数,用于在引用计数达到 0 时释放资源。
使用 kref_put
函数可以避免由于引用计数器未正确管理引用计数而导致的内存泄漏和资源占用过多等问题。
3)kfree_rcu
kfree_rcu是Linux内核中提供的一种资源释放接口,用于在RCU(Read-Copy-Update)保护下释放内存。RCU是一种经典的读写锁算法,用于保护共享的数据结构,它的特点是在读的过程中不需要获取锁,在写的过程中通过复制一份数据来保证读操作不受写操作的影响。因此在释放内存时,需要使用RCU使得所有对该内存的访问都已完成,否则可能会触发未定义的行为。kfree_rcu接口是在RCU保护下调用kfree接口来释放内存所使用的函数。+
4)atomic_dec()
是一个原子操作接口,用于将一个整数变量减小 1,并保证这个操作是原子的。
在并发程序中,如果多个线程同时对同一个变量进行修改操作,可能会产生竞争条件(Race Condition)的问题。其中一种解决方式是使用原子操作,即将整个操作作为一个不可分割的单元执行,从而保证操作的完整性。atomic_dec() 就是 Linux 内核中提供的一种原子减 1 操作。
使用 atomic_dec() 接口时,需要将待减小的整数变量以指针的方式传入函数中。函数会自动将该变量减小 1,并返回减小后的结果。该操作是原子的,也就是说,在该操作执行完之前,任何其他线程无法修改该变量。
5)container_of
是一个宏定义,常用于 C 语言中的链表实现中,用于从链表节点的地址计算出整个数据结构的地址。它的定义和用法如下:
#define container_of(ptr, type, member) \((type *)((char *)(ptr) - offsetof(type, member)))struct my_struct {int x;float y;struct list_head list;
};
ptr
:指向结构体中某个成员的指针,例如&some_struct.list
。type
:结构体类型,例如struct my_struct
。member
:结构体中某个成员的名称,例如list
。
那么 container_of(&some_struct.list, struct my_struct, list)
的计算过程如下:
- 首先使用
offsetof()
宏计算出结构体中list
成员相对于结构体首地址的偏移量。 - 然后使用
(char *)
把ptr
转换为char *
类型,方便执行指针运算。这里使用的是char *
而不是其他类型的指针,是因为char
类型的大小为 1 字节,所以可以精确计算出指针偏移量。 - 对
ptr
进行指针减法运算,结果为&(some_struct) - offsetof(struct my_struct, list)
。也就是说,这里减去了list
成员相对于整个结构体首地址的偏移量,从而得到了整个结构体的首地址。 - 最后使用
(type *)
把结果强制转换为结构体类型struct my_struct *
,即可得到整个结构体的地址。
需要注意的是,container_of()
的使用必须保证 ptr
指向的是某个结构体成员,否则计算结果将不正确。另外,该宏也不支持嵌套结构体。
5)wait_for_completion() 函数
是 Linux 内核中的一个同步原语,它用于等待一个完成量被另一个进程或线程完成。等待队列和 completion 结构体在 Linux 内核中被广泛使用,比如读写锁、自旋锁、信号量、定时器等都会用到它们。
在调用 wait_for_completion() 函数之前,首先要初始化一个 completion 结构体,而这个结构体通常被作为一个等待队列中的头结点使用,用于等待某个事件的完成。
当一个线程或进程执行 wait_for_completion() 函数时,如果它所等待的事件还没有完成,那么就会进入睡眠状态(即挂起当前线程或进程),直到所等待的事件完成,并调用 complete() 函数告知等待队列中的所有等待者事件已经完成为止。此时 wait_for_completion() 函数才返回,线程或进程才被唤醒,接着继续执行下面的代码。
6)spin_unlock_irqrestore() 函数
是用于解锁自旋锁并恢复中断的函数。在 Linux 内核中,自旋锁是一种线程同步机制,用于保护共享资源免受并发访问的干扰。当一个线程获取了自旋锁之后,其他线程会被阻塞,直到该线程释放自旋锁。
在多核CPU系统中,中断处理程序在运行时可能会产生竞争问题。当中断处理程序需要访问被自旋锁保护的共享资源时,需要临时禁止本地CPU中断以确保同步。函数 spin_lock_irqsave() 和 spin_unlock_irqrestore() 提供了这项功能,spin_lock_irqsave() 禁止中断,并尝试获取自旋锁。spin_unlock_irqrestore() 函数则释放自旋锁,并在解锁后恢复特定的中断状态。
因此 spin_unlock_irqrestore() 函数用于解锁一个被自旋锁保护的资源,并将中断的状态恢复为调用 spin_lock_irqsave() 时的状态,以避免干扰其他需要使用该状态的程序。
7)spin_lock_irqsave() 函数
是 Linux 内核中用于获得自旋锁并且禁用中断的函数。
自旋锁是一种在多线程环境下保护共享资源的机制,当多个线程尝试往同一个共享资源中写入数据时,自旋锁能够确保同一时刻只有一个线程能够访问该资源,从而避免竞态条件的出现。
spin_lock_irqsave() 函数在获取自旋锁时会先禁止中断,确保当前 CPU 不会被切换到别的上下文中执行其他的中断处理程序。在获取自旋锁成功后,函数会返回一个无符号整数值,这个值包含了此时 CPU 执行中断的状态,以便后续使用 spin_unlock_irqrestore() 函数恢复当前 CPU 的中断状态。
8)getenv() 函数
是一个 C 标准库函数,用于获取环境变量的值。它的原型如下:
char *getenv(const char *name);
传递一个环境变量名 name
,函数将返回该环境变量的值,如果该环境变量不存在,则返回 NULL。
使用方法示例:
char *path = getenv("PATH");
if (path != NULL) {printf("PATH=%s\n", path);
}
上述代码将获取环境变量名为 PATH
的值,并打印出来。
相关文章:
Linux学习笔记(2)--一些内核接口
1)dump_stack dump_stack()是Linux内核中的一个函数,用于在内核中输出当前的函数调用栈。该函数会输出当前线程(或进程)的函数调用栈信息,以及相应的调用地址和虚拟内存地址等信息,一般用于诊断程序运行时…...

学习风`宇博客用户权限菜单模块
文章目录 用户-角色-菜单-资源 各表关系图菜单 和 路由菜单表及分析分析 /api/admin/user/menus接口MenuServiceImpl#listUserMenus接口返回示例及分析 前端代码分析menu.jsSideBar.vue 接口权限控制资源表 及 分析分析 WebSecurityConfig权限控制整体流程先说登录UserDetailsS…...

centos7.6部署ELK集群(一)之elasticsearch7.7.0集群部署
32.3. 部署es7.7.0 32.3.1. 下载es(各节点都做) wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.7.0-linux-x86_64.tar.gz 32.3.2. 解压至安装目录(各节点都做) tar -xvf elasticsearch-7.7.0-li…...

leetcode142. 环形链表 II
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数…...
Linux: network: dummy 类型网络接口
文章目录 参考创建一个重要的用途是在container平台的应用dpdk相关的一个用途另一个用途ChatGPT的回复参考 https://tldp.org/LDP/nag/node72.html 这里举了一个例子,说为什么需要dummy类型的接口:就是一个类local loopback的一个接口,当应用需要给另一个本地的应用发送包的…...
java记录-lambda表达式、接口应用、方法引用
基本形式 (str)->{System.out.println(str) };调用作为参数的接口实例的方法 1、用一个类实现接口,然后使用该类实例调用方法 2、匿名内部类 3、在 接口(不能是抽象类) 有且只有一个抽象方法时,可以使用lamda表达式来重写这个…...

AI写作机器人-ai文章生成器在线
使用AI续写生成器,让内容创作事半功倍! 随着人工智能技术的不断进步和应用,AI续写生成器的出现为内容创作带来了全新的革命。这种技术可以让你的写作事半功倍,让你轻松生成高质量的文章和内容。在这篇文章中,我们将介绍…...
HarmonyOS原子化服务卡片整改、下架、升级失败部分原因及处理办法
随着HarmonyOS应用体系相关规则、团队的不断发展和完善,早期上架运营的HarmonyOS原子化服务卡片,很多都收到了整改、下架的通知,主要集中在用户协议、隐私声明、服务卡片的设计规范性等细节方面的问题;需要进行优化调整升级才行。…...

博客系统测试报告【可上线】
目录 1、测试概述 1.1、项目名称 1.2、测试时间 1.3、编写目的 1.4、测试范围 2、测试计划 2.1、测试用例 2.1.1、注册/登录模块 2.1.2、个人中心模块 2.1.3、找回密码模块 2.1.4、博客主列表模块 2.1.5、个人博客列表模块 2.1.6、个人草稿列表模块 2.1.7、博客详…...

shell中的for循环和if判断
一.编写脚本for1.sh,使用for循环创建20账户,账户名前缀由用户从键盘输入,账户初始密码由用户输入,例如: test1、test2、test3、.....、 test10 1.创建脚本for1.sh [rootserver ~]# vim for1.sh 2.编写脚本for1.sh 3.执行脚本for1.sh [roo…...

【Unity入门】16.脚本引用组件
【Unity入门】脚本引用组件 大家好,我是Lampard~~ 欢迎来到Unity入门系列博客,所学知识来自B站阿发老师~感谢 (一)脚本引用普通组件 (1)点击控制音频播放 还记得我们的车载音乐AudioSource吗?…...

无线蓝牙耳机哪款音质好?目前音质最好的无线蓝牙耳机推荐
现如今,蓝牙耳机已经是一个非常实用且常见的数码产品了,不少人喜欢戴着蓝牙耳机听歌,玩游戏。一款音质好的蓝牙耳机不止能听个响,还能给人极致的听觉享受。在此,我来给大家分享几款目前音质最好的无线蓝牙耳机…...

【云原生进阶之容器】第六章容器网络6.6.1--Cilium网络方案概述
《云原生进阶之容器》专题索引: 第一章Docker核心技术1.1节——Docker综述第一章Docker核心技术1.2节——Linux容器LXC第一章Docker核心技术1.3节——命名空间Namespace第一章Docker核心技术1.4节——chroot技术第一章Docker核心技术1.5.1节——cgroup综述...

集中式版本控制工具 —— SVN
一、简介 1️⃣ SVN 是什么? 代码版本管理工具他能记住每次的修改查看所有的修改记录恢复到任何历史版本恢复已经删除的文件 2️⃣ SVN 与 Git 相比有什么优势? 使用简单、上手快目录级权限控制,企业安全必备子目录 Checkout,…...

【Dom获取属性操作】JavaScript 全栈体系(十)
Web APIs 第四章 操作元素属性 一、操作元素常用属性 还可以通过 JS 设置/修改标签元素属性,比如通过 src更换 图片最常见的属性比如: href、title、src 等语法: 对象.属性 值 <!DOCTYPE html> <html lang"en">&…...
C# 中的多态和虚方法,如何实现多态和使用虚方法?
在 C# 中,多态(Polymorphism)是面向对象编程的基本特性之一,它允许使用不同的对象和方法来执行同一操作。C# 中实现多态的方式主要是通过虚方法和抽象类。 虚方法是一种允许子类覆盖的方法,它的实现是在运行时动态确定…...
R软件使用一些常见的问题
以下均是个人经验摸索的解决办法,使用 Rstudio 执行命令,如有高手能更好地解决问题,还望指教,提前感谢。 问题一: 有些 package 因为编辑得比较早又没有继续更新,所以需要用旧版本的 R 才能正常运行&#…...
为什么需要uboot?
一、先看概念 bootROM:一种固化在芯片内部的只读存储器(ROM),用于启动和初始化系统。BootROM 中通常包含了一些预先编写好的代码,用于完成系统启动前的基本初始化和配置,例如初始化时钟、GPIO控制器、中断…...
Qt布局实战:实现高效、美观的GUI应用程序
Qt布局实战:实现高效、美观的GUI应用程序 引言 (Introduction)1.1 Qt布局简介 (Brief introduction to Qt layouts)1.2 Qt布局的优势 (Advantages of Qt layouts) 2.布局类型 (Layout Types)2.1 水平布局 (QHBoxLayout)2.1.1 创建水平布局2.1.2 向水平布局中添加部件…...

推荐几款项目管理工具,提高你的团队协作效率
如何管理团队才能使团队发挥最大的价值,如果团队缺少协作,就会因为团队的内耗和冲突导致项目无法完成,如何提高团队协作效率呢?我们可以借助团队协作类的项目管理工具。 几个常见的项目管理工具: 1、进度猫 进度猫是…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...

使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...