热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

操作系统学习经典的进程同步互斥若干问题

文章目录1.生产者-消费者问题多生产者-多消费者2.吸烟者问题3.读者-写者问题4.哲学家进餐问题1.生产者-消费者问题问题模型:系统中有一组生产者进程和一组消费者

文章目录

  • 1. 生产者-消费者问题
    • 多生产者 - 多消费者
  • 2. 吸烟者问题
  • 3. 读者-写者问题
  • 4. 哲学家进餐问题


1. 生产者-消费者问题

问题模型:
系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用(产品:某种数据)。

生产者、消费者共享一个初始为空、大小为 n 的缓冲区。

  • 只有缓冲区没满时,生产者才能把产品放进去,否则必须等待(同步关系)。
  • 只有缓冲区不空时,消费者才能取出产品,否则必须等待(同步关系)。
  • 缓冲区必须是互斥访问的,是临界资源(互斥关系)。

在这里插入图片描述
要注意各种 P 操作的先后顺序(因为P操作会让进程阻塞),否则容易出现“死锁”现象。
在这里插入图片描述

  • 在这个问题模型中,要注意的是同步要在互斥前边

多生产者 - 多消费者


2. 吸烟者问题

问题模型:
生产者可以往桌子上放不同的材料,三个吸烟者需要拿到自己对应的材料,才可以完成吸烟动作。吸烟完成后,通知生产者,生产者才放下一个材料,三个吸烟者轮流吸烟。

主要的同步、互斥关系:

  • 桌子是一个容量为 1 的缓冲区,要互斥访问。(互斥关系)
  • 桌子上有组合一,第一个人才可以抽烟。(同步关系)
  • 桌子上有组合二,第二个人才可以抽烟。(同步关系)
  • 桌子上有组合三,第三个人才可以抽烟。(同步关系)
  • 每个吸烟者吸烟结束,供应者才可以将下一个组合放在桌子上。(同步关系)
    在这里插入图片描述
    注意这里边,互斥的关系,并没有单独设置一个信号量,因为4个负责同步的信号量,同一时刻只会有一个有值。
    • 吸烟者问题为解决“可以生产多个产品的单生产者”问题提供了一个思路。

3. 读者-写者问题

问题模型:
在这里插入图片描述

  • 多个读进程可以同时读,不会出问题。
  • 读写进程一起访问共享文件的话,会导致读进程读的并不是自己想要的那份(被写进程改了)
  • 多个写进程一起写入共享文件,可能导致数据被覆盖。

综上:

  • 只可以多个读进程一起。
  • 写进程执行的时候,其他的写进程和读进程都不能访问。
  • 读进程执行的时候,写进程不能访问。

关系如下:

  • 写 - 写(互斥)
  • 读 - 写(互斥)
    在这里插入图片描述
    读写者模式的精巧之处:

上边图里对读进程的设计中,如果没有count变量记录读进程的数量的话,会导致读进程与读进程之间也是互斥的,这并不是我们希望的。如果像上图中的设计,当多个读进程去读共享文件时(有先后顺序),只有访问共享文件的进程才会上锁,其他的读进程都不会进行上锁操作,因为通过count变量可以知道已经有读进程在读了,此时去读的话,并不会和写进程冲突,可以放心的读。同理,只有最后一个读完文件的读进程才会执行解锁操作,因为比它先读完的那些进程不能执行解锁操作,一旦解锁,写进程就会开始写入,就会造成读写冲突。

上边的这种设计存在一个问题,如上图的左下角所示,如果两个读进程并发的执行在读count变量时,都为0,会导致其中一个上锁,另一个读进程被阻塞,这是不可以的。所以再对count变量进行互斥访问,加一个mutex。


可见,上边这种方式是“读进程优先”的,只要有读进程在读,那写进程就会一直被阻塞,可能“饿死”。
再加入一个信号量 w,把写进程的优先级提一提。
在这里插入图片描述
引入 信号量w以后,并发执行的情况。

  • 读者1->读者2

    读者1读完以后,会对mutex和w都执行V操作,所以读者2可以正常读文件。

  • 写者1->写者2

    多了一个互斥信号量,所以也不会有影响。
    *写者1->读者1

    写者1执行后,w和rw上锁,此时如果有读者进程尝试访问,w信号量会让该读进程阻塞。

  • 读者1->写者1->读者2

    读者1在读的时候,写者1尝试访问,读者1会被w阻塞,当读者1执行了 V(w) 以后,写者1会对w上锁,然后被rw阻塞,如果此时,读者2尝试访问,因为写者1对w上了锁,所以读者2会被w阻塞掉。等到读者1执行了V(rw)以后(此时count一定为1,因为读者2被阻塞着),写者1可以对rw上锁,开始正常的写入。等待写者1操作结束,对rw和w解锁后,读者2就可以正常的进行了。
    这就避免了之前,写进程饥饿的问题。

  • 写者1->读者1->写者2


写者1对w和rw上锁后,开始写文件操作,此时读者1尝试访问,被w信号量阻塞,此时再有写者2尝试访问,也被w信号量阻塞,当写者1完成任务,释放rw和w后,因为读者1先于写者2上锁排队,所以w信号量被解锁后,读者1开始执行,写者2依然开始被阻塞着。

这种方法相对读者和写者都相对公平。牛逼!

总结:

  • count服务于读进程,保证读进程不互斥,mutex用于保证对count的互斥访问。
  • w用于解决写进程饥饿。

4. 哲学家进餐问题

问题模型:
在这里插入图片描述

  • 下面这种方案是不合理的,会存在死锁现象,所有的哲学家都等待自己右手边的筷子,又没有人放下自己手中的筷子。 在这里插入图片描述
    两个解决死锁问题的思路:

  1. 限制最多只允许4个哲学家进餐。
  2. 要求奇数号的哲学家先拿左手边筷子,偶数号哲学家先拿右手边筷子。
  3. 要求有人拿筷子的时候,其他人不能拿。(有书上说的是,当左右筷子都可用时才允许拿起来)

第三种方法:
在这里插入图片描述
情况说明:

  • 0号想吃饭,拿起左边筷子时,此时进程切换,2号想吃饭了,2号被mutex阻塞,只能等到0号吃完,2号采可以拿筷子、吃饭。
  • 0号拿起左右筷子,对mutex解锁后,0号开始吃饭,1号此时只能拿起左筷子,拿右筷子时被阻塞,如果此时2号也想吃饭,但它一根筷子也拿不了(即使左右都有筷子可用),因为被mutex阻塞了。只能等1号吃完,它再吃。
  • 0号拿起左右筷子,对mutex解锁后,0号开始吃饭,4号想吃饭,只能拿起左侧的筷子,拿右筷子时被阻塞
    哲学家进餐问题的关键在于解决进程死锁
    哲学家进餐问题的关键在于解决进程死锁
    哲学家进餐问题的关键在于解决进程死锁

推荐阅读
  • 本文详细解析 Skynet 的启动流程,包括配置文件的读取、环境变量的设置、主要线程的启动(如 timer、socket、monitor 和 worker 线程),以及消息队列的实现机制。 ... [详细]
  • Java高级工程师学习路径及面试准备指南
    本文基于一位朋友的PDF面试经验整理,涵盖了Java高级工程师所需掌握的核心知识点,包括数据结构与算法、计算机网络、数据库、操作系统等多个方面,并提供了详细的参考资料和学习建议。 ... [详细]
  • Maven快照版本管理及更新策略详解
    本文深入探讨了Maven中的快照版本管理和更新策略,解释了快照版本与正式版本的区别,并提供了如何配置快照更新策略的方法,以确保项目依赖始终保持最新。 ... [详细]
  • 如何高效学习鸿蒙操作系统:开发者指南
    本文探讨了开发者如何更有效地学习鸿蒙操作系统,提供了来自行业专家的建议,包括系统化学习方法、职业规划建议以及具体的开发技巧。 ... [详细]
  • HDFS数据读写流程详解
    本文详细解析了HDFS(Hadoop分布式文件系统)中的数据读写过程,包括从客户端发起请求到最终完成数据传输的每一个关键步骤。 ... [详细]
  • 本文探讨了服务器系统架构的性能评估方法,包括性能评估的目的、步骤以及如何选择合适的度量标准。文章还介绍了几种常用的基准测试程序及其应用,并详细说明了Web服务器性能评估的关键指标与测试方法。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • WebBenchmark:强大的Web API性能测试工具
    本文介绍了一款名为WebBenchmark的Web API性能测试工具,该工具不仅支持HTTP和HTTPS服务的测试,还提供了丰富的功能来帮助开发者进行高效的性能评估。 ... [详细]
  • 春季职场跃迁指南:如何高效利用金三银四跳槽季
    随着每年的‘金三银四’跳槽高峰期的到来,许多职场人士都开始考虑是否应该寻找新的职业机会。本文将探讨如何制定有效的职业规划、撰写吸引人的简历以及掌握面试技巧,助您在这关键时期成功实现职场跃迁。 ... [详细]
  • 近期在研究Java IO流技术时,遇到了一个关于如何正确读取Doc文档而不出现乱码的问题。本文将详细介绍使用Apache POI库处理Doc和Docx文件的具体方法,包括必要的库引入和示例代码。 ... [详细]
  • SQL查询与事务管理:深入解析
    本文详细介绍了SQL查询的基本结构和高级特性,包括选择、分组查询以及权限控制等内容,并探讨了事务管理中的并发控制策略,旨在为数据库管理员和开发人员提供实用指导。 ... [详细]
  • 本文深入探讨了MySQL中的高级特性,包括索引机制、锁的使用及管理、以及如何利用慢查询日志优化性能。适合有一定MySQL基础的读者进一步提升技能。 ... [详细]
  • 对于非计算机专业背景的开发者而言,如何快速掌握.NET基础知识以应对技术面试是一个挑战。本文将提供一系列实用建议,帮助读者在短时间内提高.NET基础水平。 ... [详细]
  • 深入理解线程池及其基本实现
    本文探讨了线程池的概念、优势及其在Java中的应用。通过实例分析不同类型的线程池,并指导如何构建一个简易的线程池。 ... [详细]
  • 本文详细探讨了在Java TCP编程中,如何理解和测量并发连接数、请求数及并发用户数,并提供了实际应用中的测试方法和优化建议。 ... [详细]
author-avatar
尔的依恋
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有