详解进程同步与互斥机制
- 格式:pdf
- 大小:832.31 KB
- 文档页数:6
详解进程同步与互斥机制⽬录⼀、什么是进程同步⼆、什么是进程互斥三、常见的进程同步与互斥机制
⼀、什么是进程同步
在多道批处理系统中,多个进程是可以并发执⾏的,但由于系统的资源有限,进程的执⾏不是⼀贯到底的, ⽽是⾛⾛停停,以不可预知的速度向前推进,这就是进程的异步性。
那么,进程的异步性会带来什么问题呢?举个例⼦,如果有 A、B 两个进程分别负责读和写数据的操作,这两个线程是相互合作、相互依赖的。那么写数据应该发⽣在读数据之前。⽽实际上,由于异步性的存在,可能会发⽣先读后写的情况,⽽此时由于缓冲区还没有被写⼊数据,读进程 A 没有数据可读,因此读进程 A 被阻塞。
进程同步(synchronization)就是⽤来解决这个问题的。从上⾯的例⼦我们能看出,⼀个进程的执⾏可能影响到另⼀个进程的执⾏,所谓进程同步就是指协调这些完成某个共同任务的并发线程,在某些位置上指定线程的先后执⾏次序、传递信号或消息。
再举个⽣活中的进程同步的例⼦,你想要喝热⽔,于是你打了⼀壶⽔开始烧,在这壶⽔烧开之前,你只能⼀直等着,⽔烧开之后⽔壶⾃然会发⽣响声提醒你来喝⽔,于是你就可以喝⽔了。就是说⽔烧开这个事情必须发⽣在你喝⽔之前。注意不要把进程同步和进程调度搞混了:
进程调度是为了最⼤程度的利⽤ CPU 资源,选⽤合适的算法调度就绪队列中的进程。进程同步是为了协调⼀些进程以完成某个任务,⽐如读和写,你肯定先写后读,不能先读后写吧,这就是进程同步做的事情了,指定这些进程的先后执⾏次序使得某个任务能够顺利完成。
⼆、什么是进程互斥
同样的,也是因为进程的并发性,并发执⾏的线程不可避免地需要共享⼀些系统资源,⽐如内存、打印机、摄像头等。举个例⼦:我们去学校打印店打印论⽂,你按下了 WPS 的 “打印” 选项,于是打印机开始⼯作。 你的论⽂打印到⼀半时,另⼀位同学按下了 Word 的 “打印” 按钮,开始打印他⾃⼰的论⽂。想象⼀下如果两个进程可以随意的、并发的共享打印机资源,会发⽣什么情况?
显然,两个进程并发运⾏,导致打印机设备交替的收到 WPS 和 Word 两个进程发来的打印请求,结果两篇论⽂的内容混杂在⼀起了。
进程互斥(mutual exclusion)就是⽤来解决这个问题的。当某个进程 A 在访问打印机时,如果另⼀个进程 B 也想要访问打印机,它就必须等待,直到 A 进程访问结束并释放打印机资源后,B 进程才能去访问。
实际上,像上述的打印机这种在⼀个时间段内只允许⼀个进程使⽤的资源(这也就是互斥的意思),我们将其称为临界资源,对临界资源进⾏访问的那段代码称为临界区。通俗的对⽐⼀下进程互斥和进程同步:
进程同步:进程 A 应在进程 B 之前执⾏进程互斥:进程 A 和进程 B 不能在同⼀时刻执⾏
从上不难看出,进程互斥是⼀种特殊的进程同步,即逐次使⽤临界资源,也是对进程使⽤资源的先后执⾏次序的⼀种协调。
三、常见的进程同步与互斥机制常见的进程同步与互斥机制有两种:
信号量与 PV 操作管程① 信号量与 PV 操作
包交包会!看完下⾯这段解释你绝对能够明⽩ PV 操作是啥。1965年,荷兰学者 Dijkstra 提出了⼀种卓有成效的实现进程同步和互斥的⽅法 — 信号量机制(Semaphore)。信号量其实就是⼀个变量 ,我们可以⽤⼀个信号量来表⽰系统中某种资源的数量,⽐如:系统中只有⼀台打印机,就可以设置⼀个初值为 1 的信号量。
⽤户进程可以通过使⽤操作系统提供的⼀对原语来对信号量进⾏操作,从⽽很⽅便的实现进程互斥或同步。这⼀对原语就是 PV 操作:1)P 操作:将信号量值减 1,表⽰申请占⽤⼀个资源。如果结果⼩于 0,表⽰已经没有可⽤资源,则执⾏ P 操作的进程被阻塞。如果结果⼤于等于 0,表⽰现有的资源⾜够你使⽤,则执⾏ P 操作的进程继续执⾏。
可以这么理解,当信号量的值为 2 的时候,表⽰有 2 个资源可以使⽤,当信号量的值为 -2 的时候,表⽰有两个进程正在等待使⽤这个资源。不看这句话真的⽆法理解 V 操作,看完顿时如梦初醒。2)V 操作:将信号量值加 1,表⽰释放⼀个资源,即使⽤完资源后归还资源。若加完后信号量的值⼩于等于 0,表⽰有某些进程正在等待该资源,由于我们已经释放出⼀个资源了,因此需要唤醒⼀个等待使⽤该资源(就绪态)的进程,使之运⾏下去。
我觉得已经讲的⾜够通俗了,不过对于 V 操作⼤家可能仍然有困惑,下⾯再来看两个关于 V 操作的问答:
问:信号量的值 ⼤于 0 表⽰有临界资源可供使⽤,这个时候为什么不需要唤醒进程?
答:所谓唤醒进程是从就绪队列(阻塞队列)中唤醒进程,⽽信号量的值⼤于 0 表⽰有临界资源可供使⽤,也就是说这个时候没有进程被阻塞在这个资源上,所以不需要唤醒,正常运⾏即可。
问:信号量的值 等于 0 的时候表⽰没有临界资源可供使⽤,为什么还要唤醒进程?
答:V 操作是先执⾏信号量值加 1 的,也就是说,把信号量的值加 1 后才变成了 0,在此之前,信号量的值是 -1,即有⼀个进程正在等待这个临界资源,我们需要唤醒它。
信号量和 PV 操作具体的定义如下:
实现进程互斥两步⾛即可实现进程的互斥:
定义⼀个互斥信号量,并初始化为 1把对于临界资源的访问置于 P 操作和 V 操作之间
P 操作和 V 操作必须成对出现。缺少 P 操作就不能保证对临界资源的互斥访问,缺少 V 操作就会导致临界资源永远得不到释放、处于等待态的进程永远得不到唤醒。
实现进程同步
回顾⼀下进程同步,就是要各并发进程按要求有序地运⾏。
举个例⼦,以下两个进程 P1、P2 并发执⾏,由于存在异步性,因此⼆者交替推进的次序是不确定的。假设 P2 的 “代码4” 要基于 P1 的 “代码1” 和 “代码2” 的运⾏结果才能执⾏,那么我们就必须保证 “代码4” ⼀定是在 “代码2” 之后才会执⾏。
如果 P2 的 “代码4” 要基于 P1 的 “代码1” 和 “代码2” 的运⾏结果才能执⾏,那么我们就必须保证 “代码4” ⼀定是在 “代码2” 之后才会执⾏。
使⽤信号量和 PV 操作实现进程的同步也⾮常⽅便,三步⾛:定义⼀个同步信号量,并初始化为当前可⽤资源的数量在优先级较⾼的操作的后⾯执⾏ V 操作,释放资源在优先级较低的操作的前⾯执⾏ P 操作,申请占⽤资源
配合下⾯这张图直观理解下:
⽣产者和消费者问题
下⾯我们利⽤信号量和 PV 操作来解决经典的进程同步和互斥问题:⽣产者和消费者问题。
【问题描述】:系统中有⼀组⽣产者进程和⼀组消费者进程,⽣产者进程每次⽣产⼀个产品放⼊缓冲区,消费者进程每次从缓冲区中取出⼀个产品并使⽤。任何时刻,只能有⼀个⽣产者或消费者可以访问缓冲区。
由题可知,⽣产者、消费者共享⼀个初始为空、⼤⼩为 n 的缓冲区,我们从题⽬中提炼出同步与互斥关系:
同步关系 1:只有缓冲区没满时(优先级⾼),⽣产者才能把产品放⼊缓冲区(优先级低),否则必须等待同步关系 2:只有缓冲区不空时(优先级⾼),消费者才能从中取出产品(优先级低),否则必须等待互斥关系:缓冲区是临界资源,各进程必须互斥地访问。既然这个题⽬有两个同步关系和⼀个互斥关系,那么我们就需要两个同步信号量和⼀个互斥信号量:empty:同步信号量(对应同步关系 1),表⽰⽣产者还能⽣产多少,即还能放⼊缓冲区多少产品,该数量⼩于等于 0,则⽣产者不能进⾏⽣产。 初始化为 n。full:同步信号量(对应同步关系 2),表⽰消费者还能从缓冲区取出多少,即当前缓冲区已有产品的数量,该数量⼩于等于 0,则消费者不能进⾏读取。初始化为 0。mutex:互斥信号量,实现对缓冲区的互斥访问。初始化为 1。
代码如下,注意各个 PV 操作的配对:
② 管程
管程有⼀个重要特性:在⼀个时刻只能有⼀个进程使⽤管程。进程在⽆法继续执⾏的时候不能⼀直占⽤管程,否则其它进程将永远不能使⽤管程。也就是说管程天⽣⽀持进程互斥。
其实使⽤管程是能够实现信号量的,并且也能⽤信号量实现管程。但是管程封装的⽐较好,相⽐起信号量来需要我们编写的代码更少,更加易⽤,这也就是 Java 采⽤管程机制的原因,synchronized 关键字及 wait()、notify()、notifyAll() 这三个⽅法都是管程的组成部分。把管程翻译为 Java 领域的语⾔,就是管理类的成员变量和成员⽅法,让这个类是线程安全的。
以上就是详解进程同步与互斥机制的详细内容,更多关于进程同步与互斥机制的资料请关注其它相关⽂章!