【干货】同步与互斥的失败例子

韦东山老师最新录制的驱动大全之<<同步与互斥>>收费视频已经在淘宝上架销售 ,一共7节,良心价29元,同时已经同步到CSDN , 51CTO , 电子发烧友,腾讯课堂等平台。

本文是其中一节《同步与互斥的失败例子》视频配套文档,

《同步与互斥的失败例子》免费试看版(2分钟,完整版7分46秒):

《同步与互斥的失败例子》完整版 购买链接:

https://item.taobao.com/item.htm?id=620987021249  (复制到浏览器打开)

光看文档可能难度稍大,建议结合视频进行学习;gg完毕,开始干货。


1.2 同步与互斥的失败例子

注意:本节在GIT上没有源码。

GIT地址:

git clone https://e.coding.net/weidongshan/01_all_series_quickstart.git

一句话理解同步与互斥:我等你用完厕所,我再用厕所。什么叫同步?就是条件不允许,我要等等。什么是互斥?你我早起都要用厕所,谁先抢到谁先用,中途不被打扰。

同步与互斥经常放在一起讲,是因为它们之间的关系很大,“互斥”操作可以使用“同步”来实现。我“等”你用完厕所,我再用厕所。这不就是用“同步”来实现“互斥”吗?有时候看代码更容易理解,伪代码如下:

01 void  抢厕所(void)
02 {
03    if (有人在用) 我眯一会;
04    用厕所;
05    喂,醒醒,有人要用厕所吗;
06 }

假设有A、B两人早起抢厕所,A先行一步占用了;B慢了一步,于是就眯一会;当A用完后叫醒B,B也就愉快地上厕所了。

在这个过程中,A、B是互斥地访问“厕所”,“厕所”被称之为临界资源。我们使用了“休眠-唤醒”的同步机制实现了“临界资源”的“互斥访问”。

上面是一个有“味道”的例子,回到程序员的世界,一个驱动程序同时只能有一个APP使用,怎么实现?

1.2.1 失败例子1

01 static int valid = 1;
02
03 static ssize_t gpio_key_drv_open (struct inode *node, struct file *file)
04 {
05      if (!valid)
06      {
07              return -EBUSY;
08      }
09      else
10      {
11              valid = 0;
12      }
13
14      return 0; //成功
15 }
16
17 static int gpio_key_drv_close (struct inode *node, struct file *file)
18 {
19      valid = 1;
20      return 0;
21 }
22

看第5行,我们使用一个全局变量valid来实现互斥访问。这有问题吗?很大概率没问题,但是并非万无一失。

注意:编写驱动程序时,要有系统的概念,程序A调用驱动程序时,它可能被程序B打断,程序B也去调用这个驱动程序。下图是一个例子,程序A在调用驱动程序的中途被程序B抢占了CPU资源:

程序A执行到第11行之前,被程序B抢占了,这时valid尚未被改成0;程序B调用gpio_key_drv_open时,发现valid等于1,所以成功返回0;当程序A继续从第11行执行时,它最终也成功返回0;这样程序A、B都成功打开了驱动程序。

注意:在内核态,程序A不是主动去休眠、主动放弃CPU资源;而是被优先级更高的程序B抢占了,这种行为被称为“preempt”(抢占)。

1.2.2 失败例子2

上面的例子是不是第5行到第11行的时间跨度大长了?再优化一下程序行不行?代码如下:

01 static int valid = 1;
02
03 static ssize_t gpio_key_drv_open (struct inode *node, struct file *file)
04 {
05      if (--valid)
06      {
07              valid++;
08              return -EBUSY;
09      }
10      return 0;
11 }
12
13 static int gpio_key_drv_close (struct inode *node, struct file *file)
14 {
15      valid = 1;
16      return 0;
17 }
18

第5行先减1再判断,这样可以更大概率地避免问题,但是还是不能确保万无一失。对数据的修改分为3步:读出来、修改、写进去。请看下图:

进程A在读出valid时发现它是1,减1后为0,这时if不成立;但是修改后的值尚未写回内存;假设这时被程序B抢占,程序B读出valid仍为1,减1后为0,这时if不成立,最后成功返回;轮到A继续执行,它把0值写到valid变量,最后也成功返回。这样程序A、B都成功打开了驱动程序。

1.2.3 失败例子3

前面2个例子,都是在修改valid的过程中被别的进程抢占了,那么在修改valid的时候直接关中断不就可以了吗?

01 static int valid = 1;
02
03 static ssize_t gpio_key_drv_open (struct inode *node, struct file *file)
04 {
05       unsigned long flags;
06       raw_local_irq_save(flags); // 关中断
07      if (--valid)
08      {
09              valid++;
10              raw_local_irq_restore(flags);  // 恢复之前的状态
11              return -EBUSY;
12      }
13       raw_local_irq_restore(flags);          // 恢复之前的状态
14      return 0;
15 }
16
17 static int gpio_key_drv_close (struct inode *node, struct file *file)
18 {
19      valid = 1;
20      return 0;
21 }

第06行直接关中断,这样别的线程、中断都不能来打扰本线程了,在它读取、修改valid变量的过程中无人打扰。没有问题了?

对于单CPU核的系统上述代码是没问题的;但是对于SMP系统,你只能关闭当前CPU核的中断,别的CPU核还可以运行程序,它们也可以来执行这个函数,同样导致问题,如下图:

假设CPU 0上进程A、CPU1上进程B同时运行到上图中读出valid的地方,它们同时发现valid都是1,减减后都等于0,在第07行判断条件都不成立,所以在第14行都可以返回0,都可以成功打开驱动。

推荐阅读:

    专辑|Linux文章汇总

    专辑|程序人生

    专辑|C语言

嵌入式Linux

微信扫描二维码,关注我的公众号 

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

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

相关文章

微型计算机计算机钢琴,微型计算机原理及接口技术钢琴课程设计.doc

高频电子线路课程设计题目&#xff1a; 高 频 功 率 放 大 器 .班级&#xff1a; 08级通信1班 .姓名&#xff1a; 马宗祥 .学号&#xff1a; P081513166 .成绩&#xff1a; .组内分工成员及分工&#xff1a;程冲冲&#xff1a;低频放大马云、吴欣萌&#xff1a;振荡及调制洪学军…

TCP三次握手

以下是我做的实验 &#xff0c;180.97.33.108 是百度 以下是我自己画的图 转载于:https://www.cnblogs.com/heben/p/7879439.html

微软TechEd 2006亲历(六):微软新一代系统管理平台面纱待揭

<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />对于企业网络管理人员&#xff0c;也许没有想到微软将陆续提供it系统&#xff08;包括存储&#xff09;的管理工具。利用这些管理工具&#xff0c;企业将可以轻松、便捷地管理企业…

Linux中断子系统-通用框架处理

背景Kernel版本&#xff1a;4.14ARM64处理器&#xff0c;Contex-A53&#xff0c;双核使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio1. 概述《Linux中断子系统&#xff08;一&#xff09;-中断控制器及驱动分析》讲到了底层硬件GIC驱动&#xff0c;以及Arch-Specif…

接口测试工具-fiddler的运用

本篇主要介绍一下fiddler的基本运用&#xff0c;包括查看接口请求方式&#xff0c;状态响应码&#xff0c;如何进行接口测试等 一&#xff0e;Fiddler的优点 独立的可以直接抓http请求小巧、功能完善快捷、启动就行代理方便二&#xff0e;什么是Fiddler Fiddler是一个http协议调…

微电子科学与工程要学计算机吗,微电子科学与工程专业就业前景如何 有前途吗...

微电子科学与工程专业就业前景如何&#xff1f;有前途吗&#xff1f;下面小编为大家整理了相关内容&#xff0c;以供参考&#xff0c;一起来看看吧&#xff01;微电子科学与工程专业就业前景微电子科学与工程专业近年来也逐渐热火起来了&#xff0c;竞争力也很大。微电子专业一…

利用Excel VBA畫出所有圖標

有時候﹐常感覺﹐恰當的使用Excel的VBA做些開發﹐常常收到事半功倍的效果的。從Birdshome的博客中看到這篇貼深有感觸﹐當然﹐自己以前也是使用過一段時間的VBA開發的﹐直到使用.net之后就沒有再搞那玩意兒了﹐唉....﹐感嘆一下先。順便把那里jinta2001的Excel文檔轉上來。呵呵…

我的丈母娘

2020年9月17日12点46分&#xff0c;刚进入新居我终于还是要写这篇文章了&#xff0c;想了很久&#xff0c;我觉得写一篇文章来记录下我的丈母娘。前段时间&#xff0c;小云妈妈骑车不小心把鼻子给摔破了&#xff0c;很严重&#xff0c;二哥马上回家带老人到医院检查并做了手术。…

学法语,加油!

我家小猪又折腾法语了.在大学的时候她就不学无术&#xff0c;当我专心治学的时候&#xff0c;她总是手捧闲书作认真状&#xff1b;正儿八经上课时间&#xff0c;大部分还是可以认真度过&#xff0c;但是逢到计算机课&#xff0c;她就全傻了&#xff0c;是的&#xff0c;她是计算…

华南理工大学广州学院计算机二级,华南理工大学广州学院学子在第三届“泰迪杯”数据分析职业技能大赛中荣获佳绩...

12月19日&#xff0c;第三届泰迪杯数据分析职业技能大赛落下帷幕并公示了获奖名单。华南理工大学广州学院获得国家二等奖一项&#xff0c;国家三等奖两项的好成绩&#xff0c;这是我华南理工大学广州学院首次有组织地参与该赛事。本次竞赛由计算机工程学院组织&#xff0c;同时…

OpenGL程序运行提示“glut32.dll丢失问题”

调试环境&#xff1a; Win10 (x64) &#xff0c;VS2015 解决方案 &#xff08;1&#xff09;将gult32.dll&#xff0c;glut.dll复制到C:\WINDOWS\SysWOW64 (如果是32位操作系统&#xff0c;则是WINDOWS\system32这个文件下) &#xff08;2&#xff09;将GL文件夹的路径添加到vs…

华为突然宣布,对物联网下手了!

5G时代到来物联网技术的应用离我们越来越近智慧交通、智能家庭、智慧园区越来越多的融入到我们的生活当中但国内物联网人才短缺每年人才缺口达百万之多作为5G技术的先锋华为云特别推出【IoT物联网开发全栈成长计划】三大阶段&#xff0c;从学习到实践全流程提升物联网开发技能还…

Linux内核品读 /基础组件/ 模块机制快速入门

哈喽&#xff0c;我是杰克吴&#xff0c;继续记录我的学习心得。一、关于兴趣的几点思考1. 享受不是兴趣&#xff0c;愿意付出才是&#xff1a;兴趣很容易跟享受混淆。享受是被动的&#xff0c;无需付出&#xff1b;而兴趣则要求你甘愿为了这件事情付出努力。2.任何事情&#x…

台式计算机时间不准,每天开机电脑时间都不正确怎么办?试试这个办法!

原标题&#xff1a;每天开机电脑时间都不正确怎么办&#xff1f;试试这个办法&#xff01;上面电脑运用时间长了&#xff0c;经常会出现开机提示时间不正确&#xff0c;在系统上设置好时间后&#xff0c;第二天开机电脑时间还不正确&#xff0c;是什么原因呢&#xff1f;无论是…

Ajax与WebGIS

现在越来越多的桌面应用转向Web平台&#xff0c;而人们也一直希望日益丰富的Web应用能够做到简单易用、高效并具有良好的交互性能。随着Google推出Google Maps、GMail等一系列服务让人们看到了曙光&#xff0c;感受到一种全新的Web使用体验。这种体验的显著特点就是无需下载、安…

剑指offer(20)包含min函数的栈

题目描述 定义栈的数据结构&#xff0c;请在该类型中实现一个能够得到栈最小元素的min函数。 题目分析 首先一开始我们分析得到最小值肯定要比较嘛&#xff0c;和栈里面的数据一一比较&#xff0c;但是栈这种数据结构&#xff0c;你又只能和栈顶弹出来的数据进行比较&#xff0…

杀除橙色八月的病毒

特征&#xff1a;在c 目录下发现了一个这样的文件0A5021.exe,而且在启动里也存在。即使你在安全模式下&#xff0c;他还是自动运行起来的&#xff0c;而且这个程序把你的杀毒软件禁止掉&#xff0c;不能运行杀毒软件。解决方案&#xff1a;删除一下文件&#xff1a; C:\Program…

c语言从1打印到100再打印到1该如何编写?

我觉得这是一个送分题&#xff0c;奈何知乎人才太多了&#xff0c;给出了各种古怪的写法&#xff0c;如果是做项目的话&#xff0c;我比骄建议一些正常的写法&#xff0c;就是大家都能看得懂的&#xff0c;不要搞什么花里胡哨&#xff0c;不过你要是交流的话&#xff0c;既然是…

南京大学2021计算机考研复试线是多少,34所自划线院校2021考研复试分数线-2021南京大学考研分数线已公布...

2021南京大学考研复试分数线已公布&#xff01;点击查看>>34所自划线院校2021考研复试分数线。2021考研分数线变化趋势会是怎样的呢&#xff1f;战过初试•赢过复试>>中公考研陪你决战考研复试场​南京大学2021年硕士研究生复试基本分数线一、学术学位报考学科门类…

有人知道 I3C 吗?

我们知道I2C、SPI、UART、但是应该很少有人知道I3C&#xff0c;不过它确实是存在的。在完善的I2C接口标准之后&#xff0c;I3C即将进入嵌入式市场。I3C标准由MIPI联盟开发&#xff0c;现已扩展到更广泛的市场&#xff0c;该标准将I2C&#xff0c;UART和SPI组合为10Mbit / s&…