lab7同步互斥原理

fork()是怎么实现的
多进程并发运行,导致多个进程间有资源共享,比如CPU、内存,因此存在不确定性和不可重现,可能导致多次运行结果不一致。因此操作系统需要利用同步机制在并发执行的同时,保证一些操作是原子操作。
原子操作是指一次不存在任何中断或失败的操作
类比事务的原子性:要么操作成功完成,要么操作没有执行,不会出现部分执行的状态。
在这里插入图片描述
在这里插入图片描述
互斥是指一个进程占用了某个资源,其他进程都不能使用该资源;死锁是指多个进程各占有了一部分资源,形成了循环等待;饥饿是指其他进程轮流占用资源,一个进程一直得不到资源。

进程同步方法

1、临界区

同步:协调多线程对共享数据的访问,任何时刻只能有一个线程执行临界区代码
临界区实现方式(实现进程同步的方法):
一,禁用中断,进入临界区后不响应中端;(仅限于单处理器)
二,软件方式,共享变量协调;(比较复杂)
Peterson算法(适用于两个进程之间)
turn表示谁进入临界区,flag【】表示进程是否准备好进入临界区
在这里插入图片描述
如果多个进程之间的同步问题,flag就会变多,turn只有一个
三,借用操作系统提供高级的抽象编程方法——原子操作指令(单处理器或多处理器均可)
更高级的抽象方法实际是借助硬件的同步原语来实现的。硬件提供了一些同步原语,包括中断禁用、原子操作指令等,**从硬件上保证多个操作的原子性。**实现方式有锁、信号量。

2、锁

锁是一个抽象的数据结构,由一个二进制变量(锁定/解锁)和两个操作原语(锁的请求和锁的释放)组成。二进制变量用于标志锁的状态,**锁的请求使锁在被释放前一直等待,并且使进程得到锁,这两者是原子的,释放锁时唤醒其他等待锁的进程。**内部基于CPU体系结构提供的一些特殊的原子操作指令,这些指令把若干个指令合并为一次原子操作,保证不会出现部分执行的状态。这些原子操作指令包括测试和置位指令(Test-and-Set,即TS指令,返回内存地址中的值,并将其置为1)、交换指令(交换内存中的两个值)。
基于TS指令可以实现如下图所示的自旋锁,自旋锁的缺点是线程等待时消耗CPU时间。
在这里插入图片描述
针对自旋锁的问题,出现了无忙等待锁,当锁已经被占用时,将自身线程放入等待队列,并调用调度程序。当其他线程释放锁时会将所有等待中的线程重新唤醒。
在这里插入图片描述
上面的锁使用TS原子指令来实现的,也可以用交换指令(原子指令)来实现。
在这里插入图片描述

3、信号量

信号量与管程也是进程间通信的方式。信号量是与锁在同一层级实现的,是操作系统提供的一种协调共享资源访问的方法。信号量由操作系统管理,操作系统作为管理者地位是高于进程的。
在这里插入图片描述
信号也是一种抽象的数据类型,由一个整型变量(sem)和两个原子操作组成。P()操作使sem减一,若sem<0进入等待,否则继续。V()操作使sem加一,如果加一后sem仍然小于等于零,代表还有线程在等待使用资源,此时就唤醒一个等待进程。因此信号量实际是一个被保护的整型变量,只能通过PV进行操作,操作系统保证PV操作的原子性。通常假定信号量是公平的,线程不会无线阻塞在P操作,可以假定信号量等待时按照先进先出排队的。而自旋锁是无法实现先进先出的,因为它需要占用CPU资源不停查询锁是否空闲,无法指定进入临界区的顺序。
在这里插入图片描述
生产者-消费者问题
在这里插入图片描述
信号量存在如下问题
在这里插入图片描述

4、管程(条件变量)

管程是一种用于多线程互斥访问共享资源的程序结构,采用面向对象的方法,简化线程间的同步控制,保证任意时刻最多只有一个线程执行管程代码,管程与临界区的区别是在管程中的线程可临时放弃管程的互斥访问,等待事件出现时恢复,而临界区只有线程退出临界区才能放弃互斥访问。

经典问题

1、哲学家就餐问题

用信号量来给出的方案
在这里插入图片描述

2、读者-写者问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值