自旋锁--死锁

本文内容整理自B站视频教程

自旋锁定义
内核发生访问资源冲突的时候,可以有两种锁的解决方案选择:一个是原地等待,一个是挂起当前进程,调度其他进程执行(休眠)。

spinlock是内核中提供的一种比较常见的锁机制,自旋锁是原地等待的方式解决资源冲突的,即一个线程获取了一个自旋锁后,另一个线程期望获取该自旋锁,获取不到,值呢挂钩原地“打转”(忙等待,仍然占有CPU,但不会去休眠)。

自旋锁优点

注意事项:

  1. 系统性能下降,cpu在请求自旋锁时,仅仅是等待自旋锁,当共享资源较大,执行单元操作时间较长时会导致。
  2. 造成死锁的现象,当某个cpu已经拿到锁之后,再去申请锁时就会发生。
  3. 内核的崩溃,当cpu拿到锁执行下面程序时,如果遇到阻塞发生例如copy_from_usr() copy_to_usr() kmalloc()和msleep()等调用。
  4. 进程拥有自旋锁的时候,该CPU上是禁止抢占的。
  5. 一般用于多CPU之间的资源竞争,单核上一般不用。
  6. 由于自旋锁的这个忙等待的特性,注定了他使用场景上的限制--自旋锁不应该被长时间的持有(消耗CPU资源),一般应用在中断上下文。

自旋锁的死锁

死锁的两种情况

上面这种有一个条件是在单核CPU(可用ps -ef| grep softirq查看是否是单个CPU,因为一个softirq对应一个CPU),因为进程A此时拥有自旋锁了,该CPU被禁止抢占了,此时A内核阻塞了,又放弃了CPU占用,进程B申请自旋锁后一直自旋,一直占用CPU,其他进程,包含进程A又无法获得CPU了,导致了死锁。

 死锁举例:

如何避免死锁

第一条意思是针对中断程序,拥有自旋锁时候要禁止中断;第三条意思是同一个任务不能申请两次锁,不然会死锁。

按同样顺序申请锁是指两个进程都要申请A和B两种锁,两个进程必须按照同样顺序沈亮A和B两种锁。

下面是一个死锁的实例代码:

static int major = 237;
static int minor = 0;
static dev_t devno;
static struct cdev cdev;
struct device *class_dev = NULL;
struct class *cls;static spinlock_t lock;
static int flage = 1;static int hello_open (struct inode *inode, struct file *filep)
{printk("hello_open()\n");spin_lock(&lock);if(flage != 1){spin_unlock(&lock);return -EBUSY;}flage = 0;return 0;
}
static int hello_release (struct inode *inode, struct file *filep)
{printk("hello_release()\n");flage = 1;spin_unlock(&lock); //这里在close文件的时候释放自旋锁,模拟死锁场景return 0;
}#define KMAX_LEN 32
char kbuf[KMAX_LEN+1] = "kernel";//read(fd,buff,40);static ssize_t hello_read (struct file *filep, char __user *buf, size_t size, loff_t *pos)
{int error;if(size > strlen(kbuf)){size = strlen(kbuf);}if(copy_to_user(buf,kbuf, size)){error = -EFAULT;return error;}return size;
}
//write(fd,buff,40);
static ssize_t hello_write (struct file *filep, const char __user *buf, size_t size, loff_t *pos)
{int error;if(size > KMAX_LEN){size = KMAX_LEN;}memset(kbuf,0,sizeof(kbuf));if(copy_from_user(kbuf, buf, size)){error = -EFAULT;return error;}printk("%s\n",kbuf);return size;
}static struct file_operations hello_ops = 
{.open = hello_open,.release = hello_release,.read = hello_read,.write = hello_write,
};
static int hello_init(void)
{int result;int error;printk("hello_init \n");spin_lock_init(&lock); //初始化自旋锁result = register_chrdev( major, "hello", &hello_ops);if(result < 0){printk("register_chrdev fail \n");return result;}cls = class_create(THIS_MODULE, "hellocls");if (IS_ERR(cls)) {printk(KERN_ERR "class_create() failed for cls\n");result = PTR_ERR(cls);goto out_err_1;}devno = MKDEV(major, minor);class_dev = device_create(cls, NULL, devno, NULL, "hellodev");if (IS_ERR(class_dev)) {result = PTR_ERR(class_dev);goto out_err_2;}return 0;out_err_2:class_destroy(cls);
out_err_1:unregister_chrdev(major,"hello");return 	result;
}
static void hello_exit(void)
{printk("hello_exit \n");device_destroy(cls, devno);class_destroy(cls);unregister_chrdev(major,"hello");return;
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
main()
{int fd;int len;char buf[64]={0};char buf2[64+1]="peng";fd = open("/dev/hellodev",O_RDWR);if(fd<0){perror("open fail \n");return;}sleep(10); //休眠时候放弃了占用CPUclose(fd);
}

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

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

相关文章

ICM20948 DMP代码详解(107)

接前一篇文章:ICM20948 DMP代码详解(106) 上一回开始解析inv_set_hw_smplrt_dmp_odrs函数中的以下代码片段: if (s->b2s_status != 0) {unsigned short lB2SMinDly = min(INV_ODR_DEFAULT_B2S, minDly_accel);lB2SMinDly = 1000/(get_multiple_56_rate(lB2SMinDly));dmp…

【C++】继承和多态常见的面试问题

文章目录 继承笔试面试题1. 什么是菱形继承&#xff1f;菱形继承的问题是什么&#xff1f;2. 什么是菱形虚拟继承&#xff1f;如何解决数据冗余和二义性&#xff1f;3. 继承和组合的区别&#xff1f;什么时候用继承&#xff1f;什么时候用组合&#xff1f; 选择题 多态概念考察…

Android gradle和maven国内镜像地址

在Android 开发中经常会出现gradle或者maven依赖下载过慢或者失败的情况&#xff0c;如果出现这种情况的话&#xff0c;那就需要使用国内镜像地址&#xff0c;本文章仅作记录&#xff0c;方便后续查取。 gradle国内镜像地址 这里提供的是腾讯的国内gradle镜像地址。 https://…

人工智能:机遇与挑战

人工智能&#xff08;AI&#xff09;作为当今世界科技发展的前沿领域&#xff0c;正在以前所未有的速度和规模影响着我们的生活和工作方式。AI技术的应用前景广阔&#xff0c;从医疗健康到金融服务&#xff0c;从教育到交通&#xff0c;再到娱乐和家庭生活&#xff0c;AI正在逐…

数字IC开发:布局布线

数字IC开发&#xff1a;布局布线 前端经过DFT&#xff0c;综合后输出网表文件给后端&#xff0c;由后端通过布局布线&#xff0c;将网表转换为GDSII文件&#xff1b;网表文件只包含单元器件及其连接等信息&#xff0c;GDS文件则包含其物理位置&#xff0c;具体的走线&#xff1…

Python爬虫的“京东大冒险”:揭秘商品类目信息

开篇&#xff1a;欢迎来到Python的奇幻森林 在这个数据驱动的时代&#xff0c;我们就像一群探险家&#xff0c;穿梭在数字的森林中&#xff0c;寻找着隐藏的宝藏——商品类目信息。今天&#xff0c;我们将带领你一起&#xff0c;用Python这把锋利的剑&#xff0c;深入京东的神…

Flutter 13 网络层框架架构设计,支持dio等框架。

在移动APP开发过程中&#xff0c;进行数据交互时&#xff0c;大多数情况下必须通过网络请求来实现。客户端与服务端常用的数据交互是通过HTTP请求完成。面对繁琐业务网络层&#xff0c;我们该如何通过网络层架构设计来有效解决这些问题&#xff0c;这便是网络层框架架构设计的初…

LLM大模型部署实战指南:部署简化流程

LLM大模型部署实战指南:Ollama简化流程,OpenLLM灵活部署,LocalAI本地优化,Dify赋能应用开发 1. Ollama 部署的本地模型(🔺) Ollama 是一个开源框架,专为在本地机器上便捷部署和运行大型语言模型(LLM)而设计。,这是 Ollama 的官网地址:https://ollama.com/ 以下是其…

Qt限制QGraphicsScene QGraphicsItem内部的移动范围

用过QGraphicsView的都知道&#xff0c;原点一般设定在view和item的中心&#xff0c;所以帮助文档和这个网友说的不一定跟我们对的上&#xff1a; 关于Qt限制QGraphicsScene内部Item的移动范围_qgraphicsitem限制移动范围-CSDN博客 首先&#xff0c;设定view的scenerect&…

电能表预付费系统-标准传输规范(STS)(27)

6.5.2.5 KeyRevisionNumber (KRN) Each SupplyGroup has one or more VendingKeys associated with it. A KRN uniquely identifies a VendingKey within the SupplyGroup. Together the SGC and KRN uniquely identify a VendingKey. 每个SupplyGroup都有一个或多个与之相关联…

git回滚间隔的提交

如果你需要回滚几个非连续的提交&#xff0c;可以使用 git revert 来选择性地撤销这些提交。这样做不会改变提交历史&#xff0c;只是会在当前分支上创建新的提交来反转指定的更改。 ### 使用 git revert 回滚间隔的提交 1. **查看提交历史**&#xff1a; 首先&#xff0c…

【数据结构-邻项消除】力扣2211. 统计道路上的碰撞次数

在一条无限长的公路上有 n 辆汽车正在行驶。汽车按从左到右的顺序按从 0 到 n - 1 编号&#xff0c;每辆车都在一个 独特的 位置。 给你一个下标从 0 开始的字符串 directions &#xff0c;长度为 n 。directions[i] 可以是 ‘L’、‘R’ 或 ‘S’ 分别表示第 i 辆车是向 左 、…

强网拟态的复现

web ez_picker 这题的考点 capoo Misc ezflag 这题涉及到kali的工具使用&#xff0c;binwalk或者formost 1.将压缩包拖进010&#xff0c;发现包含flag.zip文件&#xff0c;想到使用工具进行分离 命令&#xff1a;binwalk -e .... --run-asroot 分离流量包 得到一个文件&…

【Effective C++】阅读笔记2

1. 复制对象时要保证复制内容完整性 错误场景复现&#xff08;没有复制基类部分&#xff09; 如果一个类中包含多个成员变量或者继承了基类&#xff0c;那么在拷贝构造函数或者赋值运算符中&#xff0c;必须保证所有成员的基类部分被复制。 基类没有被复制&#xff0c;这样就都…

数组移除元素

目录 题目方法一&#xff1a;直接(暴力)求解法思路分析代码如下 方法二&#xff1a;双指针&#xff08;快慢指针&#xff09;思路分析代码如下 题目 这道题是来自于leetcode的一道算法题&#xff1a; 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于…

【Flask】二、Flask 路由机制

目录 什么是路由&#xff1f; Flask中的路由 基本路由 动态路由 路由中的HTTP方法 路由函数返回 在Web开发中&#xff0c;路由是将URL映射到相应的处理函数的过程。Flask是一个轻量级的Web应用框架&#xff0c;提供了简单而强大的路由机制&#xff0c;使得开发者能够轻松…

【IC验证_systemverilog】信号类型

IC验证_systemverilog 1.信号声明2.变量类型3.数据类型4.符号 1.信号声明 语法&#xff1a; 变量类型 信号类型 符号转换 位宽 信号名 深度&#xff1b;2.变量类型 &#xff08;1&#xff09;说明&#xff1a; systemverilog中的信号类型主要分为线网类型&#xff08;wire&a…

yt-dlp下载视频

插件官方下载地址 通过以下命令行使用 yt-dlp下载 (base) D:\tool\video>cd D:\tool\video (base) PS D:\tool\video> .\vdownlod.bat 此处输入链接或者(base) D:\tool\video>yt-dlp -f bv[extmp4]ba[extm4a] --cookies d:\Downloads\www.youtube.com_cookies.txt -…

《模拟电子技术基础》第六版PDF课后题答案详解

《模拟电子技术基础》第六版是在获首届全国优秀教材建设奖一等奖的第五版的基础上&#xff0c;总结6年来的教学实践经验修订而成的新形态教材。为满足国家人才培养的需求&#xff0c;适应新型教学模式&#xff0c;并考虑到大多数院校逐渐减少课程学时的现状&#xff0c;在不降低…

DOM---鼠标事件类型(移入移出)

移入 移出mouseenter mouseleave 在父盒子上触发&#xff0c;在孩子盒子上不触发 移入 移出mouseover mouseout全触发 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Comp…