Linux内核之互斥锁mutex_init和自旋锁spin_lock区别及用法实例(四十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🍉🍉🍉文章目录🍉🍉🍉

    • 🌻1.前言
    • 🌻2.介绍
      • 🐓2.1 互斥锁mutex_init介绍
      • 🐓2.2 自旋锁spin_lock介绍
      • 🐓2.3 用法区别
      • 🐓2.4性质和适用场景:
      • 🐓2.5 mutex_lock、 mutex_unlock 、spin_lock、spin_unlock用法
    • 🌻3.代码实例
      • 🐓3.1 互斥锁mutex_init示例
      • 🐓3.2 自旋锁spin_lock示例
      • 🐓3.3 互斥锁和自旋锁组合使用

🌻1.前言

本篇目的:Linux内核之互斥锁mutex_init和自旋锁spin_lock区别及用法实例

🌻2.介绍

  • 在Linux内核中,mutex_initspin_lock是两种常用的同步机制,用于在多线程或多处理器环境中保护共享资源,防止并发访问造成的数据不一致问题。

🐓2.1 互斥锁mutex_init介绍

  • mutex_init用于初始化一个互斥锁(mutex),它是一种睡眠锁。
  • 当一个线程尝试获取一个已经被其他线程持有的互斥锁时,该线程会被阻塞,进入睡眠状态,直到互斥锁被释放。
  • 互斥锁适用于那些可能造成较长时间阻塞的场景,因为线程睡眠状态不会消耗CPU资源。
  • 用法示例:
#include <linux/mutex.h>
struct mutex my_mutex;
void my_init_function(void) {
    mutex_init(&my_mutex); // 初始化互斥锁
}
void my_function(void) {
    mutex_lock(&my_mutex); // 获取互斥锁
    // 临界区代码
    mutex_unlock(&my_mutex); // 释放互斥锁
}

🐓2.2 自旋锁spin_lock介绍

  • spin_lock是一种自旋锁,它的工作原理是在一个循环中不断地检查锁是否可用。
  • 如果锁被占用,线程会持续检查,而不是进入睡眠状态。
  • 这意味着自旋锁适用于那些预期等待时间非常短的场景,因为自旋状态会占用CPU资源。
    用法示例:
#include <linux/spinlock.h>
DEFINE_SPIN_LOCK(my_spinlock);
void my_function(void) {
    unsigned long flags;
    spin_lock_irqsave(&my_spinlock, flags); // 获取自旋锁,并保存中断状态
    // 临界区代码
    spin_unlock_irqrestore(&my_spinlock, flags); // 释放自旋锁,并恢复中断状态
}

🐓2.3 用法区别

  1. 阻塞与自旋mutex会导致线程睡眠,不会消耗CPU资源,而spin_lock会持续占用CPU资源,直到锁被释放。
  2. 使用场景mutex适用于可能造成长时间阻塞的场景,如等待I/O操作完成。spin_lock适用于预期等待时间非常短的场景,如简单的数据结构操作。
  3. 性能影响mutex在阻塞和唤醒线程时会有较大的性能开销,而spin_lock在等待锁释放时只会占用CPU资源,没有线程切换的开销。
  4. 中断处理:在Linux内核中,自旋锁常常与中断处理相关,因为中断处理函数不能睡眠。使用spin_lock_irqsave可以在获取锁的同时关闭中断,确保临界区的原子性。
  • 选择mutex还是spin_lock取决于临界区的性质和预期的等待时间。对于可能长时间阻塞的操作,使用mutex更合适;而对于非常快速的操作,使用spin_lock可能更高效。

🐓2.4性质和适用场景:

  • mutex_init:适用于需要在内核中进行睡眠等待的同步操作,因为互斥锁(mutex)可以导致任务进入睡眠状态并被放置在等待队列中。
  • spin_lock:适用于需要在内核中进行自旋等待的同步操作,因为自旋锁(spinlock)会导致任务在一个循环中不断尝试获取锁,直到成功,而不会引起任务的睡眠。

🐓2.5 mutex_lock、 mutex_unlock 、spin_lock、spin_unlock用法

  • mutex_init:通过 mutex_init 函数初始化互斥锁,然后可以使用 mutex_lock 和 mutex_unlock 函数来获取和释放锁。
  • spin_lock:通过 spin_lock 函数获取自旋锁,通过 spin_unlock 函数释放自旋锁。

🌻3.代码实例

🐓3.1 互斥锁mutex_init示例

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mutex.h>

static DEFINE_MUTEX(my_mutex); // 定义互斥锁

static int __init my_init(void)
{
    printk(KERN_INFO "Initializing my driver\n");
    mutex_init(&my_mutex); // 初始化互斥锁
    // 其他初始化代码...
    return 0;
}

static void __exit my_exit(void)
{
    printk(KERN_INFO "Exiting my driver\n");
    mutex_destroy(&my_mutex); // 销毁互斥锁
    // 其他清理代码...
}

module_init(my_init);
module_exit(my_exit);

🐓3.2 自旋锁spin_lock示例

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>


static DEFINE_SPINLOCK(my_spinlock); // 定义自旋锁

static int __init my_init(void)
{
    printk(KERN_INFO "Initializing my driver\n");
    // 其他初始化代码...
    return 0;
}

static void __exit my_exit(void)
{
    printk(KERN_INFO "Exiting my driver\n");
}

module_init(my_init);
module_exit(my_exit);

🐓3.3 互斥锁和自旋锁组合使用

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>

static DEFINE_MUTEX(my_mutex); // 定义互斥锁
static DEFINE_SPINLOCK(my_spinlock); // 定义自旋锁

static int __init my_init(void)
{
    printk(KERN_INFO "Initializing my driver\n");
    mutex_init(&my_mutex); // 初始化互斥锁
    return 0;
}

static void __exit my_exit(void)
{
    printk(KERN_INFO "Exiting my driver\n");
    mutex_destroy(&my_mutex); // 销毁互斥锁
}

module_init(my_init);
module_exit(my_exit);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

股权融资成本GLS模型计算

一、模型公式 式中&#xff1a; r 为股权融资成本 P为股价 B为每股净资产 FROE为预测每股净资产收益率 目标&#xff1a;求解股权融资成本r 二、模型口径参考来源 PS&#xff1a;实际以代码为准 ①FROE&#xff08;预测每股净资产收益率&#xff09;: 资本市场开放与…

物联网实战--驱动篇之(五)TEA和AES加密算法

目录 一、前言 二、TEA算法 三、AES算法 四、加解密测试 五、安全性保障 一、前言 物联网的安全性是经常被提及的一个点&#xff0c;如果你的设备之间通讯没有加密的话&#xff0c;那么攻击者很容易就能获取并解析出报文的协议&#xff0c;从而根据攻击者的需要进行设备操…

c# refc# substring c# 反射c# split c# websocket c# datatable使用

在C#编程中&#xff0c;ref关键字、Substring方法、反射&#xff08;Reflection&#xff09;、Split方法、WebSocket通信以及DataTable的使用都是常见的技术和方法。下面我将逐一为您详解这些内容。 1. C# ref关键字 ref关键字在C#中用于按引用传递参数。这意味着当您将变量作…

当你的项目体积比较大?你如何做性能优化

在前端开发中&#xff0c;项目体积优化是一个重要的环节&#xff0c;它直接影响到网页的加载速度和用户体验。随着前端项目越来越复杂&#xff0c;引入的依赖也越来越多&#xff0c;如何有效地减少最终打包文件的大小&#xff0c;成为了前端工程师需要面对的挑战。以下是一些常…

vim卡死了,没有反应怎么办?

解决办法&#xff1a; 很有可能是你有个在window下的好习惯&#xff0c;没事儿就ctrl s保存文件。但是在vim里&#xff0c;ctrl s默认是发送一种流控制信号&#xff0c;通常用于停止终端的输出&#xff0c;所以你的屏幕就卡死了。 解决办法也很简单&#xff0c;按下ctrl q即…

机器学习前导——PyCharm PyTorch Python3 机器学习

机器学习前导——PyCharm & pytorch & Python3 & 机器学习 文章目录 前言PyCharmPyTorchPython3机器学习联系 前言 这学期选了《机器学习》&#xff0c;第一次接触&#xff0c;对一些专有名词很陌生。 PyCharm PyCharm是一款由JetBrains开发的软件&#xff0c…

python--递归算法篇

1、给定一个包含n1个整数的数组nums&#xff0c;其数字在1到n之间&#xff08;包含1和n&#xff09;&#xff0c; 可知至少存在一个重复的整数&#xff0c;假设只有一个重复的整数&#xff0c;请找出这个重复的数 def repeat(ls:list) -> list:#把个数超过1的数&#xff0c…

ppt技巧:如何将Word文档大纲中导入到幻灯片中?

在PowerPoint中&#xff0c;将Word文档的大纲导入到新的幻灯片是一种非常实用的技巧。以下是详细的步骤&#xff1a; 首先&#xff0c;需要打开PowerPoint软件并打开原始的幻灯片文件。 在PowerPoint的顶部【开始】菜单栏中&#xff0c;找到并点击“新建幻灯片”按钮&#xff0…

OSPF中配置VLAN通信(单臂路由)

OSPF中配置VLAN通信&#xff08;单臂路由&#xff09; 单臂路由&#xff08;One-Arm Routing&#xff09;是一种网络路由配置方式&#xff0c;常用于解决网络中的特定问题。在传统的网络架构中&#xff0c;路由器通常需要连接到多个子网或网络段&#xff0c;每个子网都需要一个…

数学知识——欧几里得算法(辗转相除法)

欧几里得算法用来求最大公约数 int gcd(int a, int b) {if(b 0) return a;else return gcd(b, a % b); } 例题&#xff1a;洛谷p1029 #include<iostream>using namespace std;#define int long long #define endl \nint x, y; int ans;int gcd(int x, int y) {if(y 0)…

Bytebase 2.15.0 - GitOps 整体升级

&#x1f514; GitOps 整体升级 新版 GitOps 和之前版本不兼容&#xff0c;如果需要升级协助&#xff0c;请联系我们。 使用访问令牌进行身份验证。支持项目中配置多个 VCS 连接器。支持在 VCS 连接器中指定数据库分组为目标&#xff08;默认情况下应用于项目中的所有数据库&…

俄罗斯yandex广告推广如何投放?

俄罗斯作为欧亚大陆的重要经济体&#xff0c;拥有庞大的互联网用户基数&#xff0c;其中Yandex作为该地区最主要的搜索引擎&#xff0c;无疑是触及目标客户群的关键渠道。云衔科技凭借专业优势与实战经验&#xff0c;为企业提供一站式Yandex广告开户及全程代运营解决方案&#…

抽象工厂模式:深入探索面向对象设计的多样性

在软件开发中&#xff0c;正确地应用设计模式对于构建可扩展、可维护和高效的系统至关重要。抽象工厂模式作为创建型设计模式之一&#xff0c;提供了一个高层接口&#xff0c;用于创建一系列相关或依赖对象&#xff0c;而无需指定它们具体的类。本文将详细介绍抽象工厂模式的概…

Ubuntu日常配置

目录 修改网络配置 xshell连不上怎么办 解析域名失败 永久修改DNS方法 临时修改DNS方法 修改网络配置 1、先ifconfig确认本机IP地址&#xff08;刚装的机子没有ifconfig&#xff0c;先apt install net-tools&#xff09; 2、22.04版本的ubuntu网络配置在netplan目录下&…

【随笔】Git 高级篇 -- 管理多分支 git rebase(二十二)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

WSL访问adb usb device

1.Windows上用PowerShell运行&#xff1a; winget install --interactive --exact dorssel.usbipd-win 2.在WSLUbuntu上终端运行&#xff1a; sudo apt install linux-tools-generic hwdata sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-too…

数据结构的魅力

数据结构这块越学越敬佩 博大精深 统计大文件中相同年龄的人的个数 public static void main(String[] args) throws Exception {String str "";String fileName "";InputStreamReader isr new InputStreamReader(new FileInputStream(fileName), Stan…

蓝桥杯嵌入式(G431)备赛笔记——RTC

// RTC time// 声明一个变量 rtc_tick 用于记录上次 RTC 处理的时间 u32 rtc_tick 0;// 声明结构体变量 D 用于存储 RTC 的日期信息 RTC_DateTypeDef D;// 声明结构体变量 T 用于存储 RTC 的时间信息 RTC_TimeTypeDef T;// RTC_proc 函数&#xff0c;用于处理 RTC 时间 void R…

【单片机毕业设计8-基于stm32c8t6的RFID校园门禁系统】

【单片机毕业设计8-基于stm32c8t6的RFID校园门禁系统】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇8基于stm32的RFID校园门禁系统 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功能介绍 -----------…

Spark-Scala语言实战(15)

在之前的文章中&#xff0c;我们学习了如何在spark中使用键值对中的学习键值对方法中的lookup&#xff0c;cogroup两种方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#…