每日一博 | 互斥那点事儿(下)
“我找到好办法了!”
没有想到,说话的人竟然是磁盘!
进程调度器瑟瑟的说:“你有方法?还是算了吧,我怕用你的方法操作系统要乱套了。”
磁盘委屈的道:“不就是刚刚冤枉你了吗,这么小气干什么!再说了,这个方法不是我想出来的,是我从文件里找到的。”
操作系统挑了挑眉毛:“哦?你找到什么文件了,让大家也瞅瞅?”
磁盘嗡嗡的转起来,很快就把文件取出来了。
“当当当当~ 这可是大师 Dijkstra 的论文,他引入了一个全新的变量类型——信号量(semaphore)。然后还为信号量设置了两种操作,P
(proberen,检测) 和 V
(verhogen,增量) 。”
”说清楚点啊,信号量是怎么个用法啊?“进程急切的问道。
“别急,让我接着看。。。Dijkstra 提出,P
操作是检测信号量是否为正值,如果不是,就阻塞调用进程。 V
操作能唤醒一个阻塞进程,让他恢复执行 。具体点的话就是这样: “
// S 为信号量 P(s): { S = S - 1 if (S < 0) { 调用该 P 操作的进程阻塞,并插入相应的阻塞队列; } }
// S 为信号量 V(s): { S = S + 1 if (S <= 0) { 从等待信号量 S 的阻塞队列里唤醒一个进程; } }
内存仔细看了代码,说:”这个实现也要求是原子操作诶,Dijkstra 这个方法很有趣啊。“
进程蒙圈了:“我怎么完全看不懂啊?内存你给我讲讲呗。”
“好,我就用最简单的一组线程举例子了:
// 线程 A,B,C , S = 1 ... P(S) //S = S - 1 若 S < 0 ,阻塞等待 购票操作 V(S) //S = S + 1 若 S <= 0, 表明有线程阻塞了,得唤醒其中一个 ...
这里的 「购票操作」 就是我们要保护的临界区,我们要保证一次只能有一个线程进入。那我们就把 S
的初始值设为 1
。当线程 A 第一个调用 P(S)
后,S
的值就变成了 0
,A 成功进入临界区。在 A 出临界区之前,线程 B 如果调用 P(S)
, S 就变成 -1
,满足 S < 0
的判断条件,线程 B 就被阻塞了。等 A 调用 V(S)
后,S
的值又变成 0
,满足 S <= 0
,就会把线程 B 唤醒,B 就能进入临界区了。“
进程恍然大悟:“原来是这样,看起来和二元锁差不多啊,但是不用忙等待了。”
内存神秘一笑:“信号量能做的可不止这些,你想想看,要是我把 S 的初始值设为 2 ,会发生什么?”
“一次能有两个线程访问临界区!”进程这次反应快多了:“也就是说 S 的初始值可以控制有多少个线程进入临界区,太厉害了!”
tobe 注:从信号量的值能看出还有多少个进程能进入临界区,如果为负数,表明有 x 个进程因为调用 P(S) 而被阻塞
“没错,所以说信号量是一个很灵活的并发机制。而且信号量还有另一个厉害的用处:
你看这两个进程有什么特别的地方?“
“emmmm,这个嘛,进程 P2 的 V
操作居然放在 P
操作的前面,而且两个操作的信号量还不是同一个。”
“没错,这样使用信号量,能让两个进程做到同步。你看,如果 P1 运行到 P(S1)
,他是不是会阻塞?”
进程认真一看,说:“没错诶,S1 初始值是 0,P1 肯定得停在这一句。让我再看看,,,如果 P1 想接着运行,就得等 P2 调用 V(S1)
把他唤醒。”
“是的,这就是同步——运行快的 P1 必须在这里停下来等 P2 运行到指定位置。两个进程的执行顺序就是这样:
也就是说 x
最终的值必然是 30,而不可能是 20。在信号量的帮助下,这两个进程达成了同步。“
进程由衷的感叹:“信号量实在是太强大了!咱们以后就用信号量来解决互斥的问题吧!”
tobe 注:在 Linux 里提供了信号量和互斥量(也就是二元锁)这两种主要机制实现互斥,不过 Linux 的信号量功能要比文章里讲得复杂得多,「UNIX 环境高级编程」这本书里写到「。。。三种特性造成了这种并非必要的复杂性」,对于一般的互斥操作,还是建议使用互斥锁(当然是阻塞而非忙等待)。稍微复杂点的锁还有「读写锁」,以后有机会再讲吧~
觉得我写的还不错的话,就点个赞吧!
如果本文对你有帮助,欢迎关注我的公众号 tobe的呓语 ,带你深入计算机的世界~ 公众号后台回复关键词【计算机】有惊喜哦~
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
AMD 加入 Blender 基金会
3 个月前我们报导过知名游戏公司育碧宣布以企业黄金会员身份加入 Blender 基金会的 Development Fund 项目,近日又有一家大公司进入了该组织,它就是 AMD。 Blender 官方在推荐中公布了该消息。AMD 加入 Blender 基金会的级别属于“Patron”(资助人),它将向基金会提供资金,以协助开发 Blender 项目。 Development Fund 项目是 Blender 的捐赠计划,支持所有人维护和改进 Blender。 Blender 表示,AMD 的资助将用于日常开发与 Vulkan 迁移,并为用户提供良好的 AMD 技术支持。 Blender 是一款用于 3D 图形设计的自由开源软件,主要使用了 C、C++ 和 Python 语言,可以运行于不同的平台。
- 下一篇
OpenJS 基金会推出 Node.js 证书,JS 开发者可以“考证”了
OpenJS 基金会近日在其官方博客公布了最新启动的专业认证计划。据介绍,此项认证计划重点关注 Node.js 开发者在专业环境中构建 Node.js 应用和服务所需的关键技能。开发者通过认证后,可获得由 OpenJS 基金会颁发和认证的证书,证书有效期为三年,其中包括 PDF 证书和数字徽章,到期后可重新认证。 正如上面提到的,此项认证主要是考查开发者构建 Node.js应用和服务所需的关键技能,所以 OpenJS 基金会也推出了两个证书来对这两种技能进行认证,这两个证书分别为 OpenJS Node.js 应用开发者证书和 OpenJS Node.js 服务开发者证书。 据官方介绍,OpenJS Node.js 应用开发者 (JSNAD) 证书非常适合具有至少两年Node.js 使用经验的开发者,有关报名或其他更多信息请点击这里进行了解。OpenJS Node.js 服务开发者 (JSNSD) 证书则更适合具有使用 Node.js 创建 RESTful 服务器以及服务的经验。详情请点此了解。 另外,两项考试的时长都为两个小时,开发者通过基于浏览器的终端进行考试,如果有需要,每项考试...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装Docker,最新的服务器搭配容器使用
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7设置SWAP分区,小内存服务器的救世主