进程间通信(一):竞争条件与相互排斥方案

进程间通信(一):进程之间的冲突与处理方式

——《现代操作系统第二章第三节》

1、问题的提出

我们想象一个假脱机打印程序。当一个进程须要打印一个文件时,它会将该文件放在一个假脱机文件夹下。还有一个进程负责周期性地检查是否有文件须要被打印,如果有就打印并将其在文件夹中删除。

简单设想。脱机文件夹中有非常多槽位,每一个槽位中存放文件名称,如果它们有两个共享的变量:out,指向下一个要被打印的文件;in,指向下一个空暇的槽位。

如图,下一个被打印的应该是4号槽,下一个入队的应该是7号槽。

如今,如果进程A、B将把文件A、B入队,如果A先读到的信息是7,而且A将7存入自己的一个记忆变量中,而这时,系统觉得已经分给了A足够的时间,于是中断A切换置进程B。进程读到的信息是7,将7存入自身的一个记忆变量中,并将int更新至8。至此B已经完毕了全部的入队操作。转而去干其它的事情。当A继续运行时。它还觉得应该将文件存到7号槽。于是A文件成功地覆盖住了B文件,而我们的B文件,永远都不会被打印。问题就出现了。

2、抽象一些概念

竞争条件:类似于上述情况,即两个或者多个进程读写某些共享数据。而最后的结果取决于进程的执行的精确时序,称为竞争条件。

(把条件理解成情况,竞争情况,貌似更加easy理解一些=。=)

相互排斥:相互排斥是一种手段。它使共享数据的进程无法同一时候对其共享的数据进行处理。

临界区:即訪问共享内存的程序片。也就是说,通过合理的安排。使得两个进程不可能同一时候处在临界区中,就能避免竞争条件。

忙等待:连续測试一个变量直至某值出现位止。(如语句while(t!=0){},那么当t不为零时。while()之后的语句将永远不会运行,这样的情况书中好像也叫挂起)

自旋锁:用于忙等待的锁。(在3-(3)中,turn即使自旋锁)

3、忙等待的相互排斥(几种实现相互排斥的方法)

(1)屏蔽中断

原理:进程进入临界区后马上屏蔽全部中断,离开后打开中断。

缺点:a、多核的系统无效(其它进程任然能够占用其它的CPU继续訪问公共内

存)

b、用户程序来控制中断会非常危急(使想一下。一个进程屏蔽中断后不再

打开中断。那你的系统就GG了)

结论:屏蔽中断对系统本身是一项非常实用的技术。但对用户进程不是一种合适的

通用相互排斥机制。

(2)锁变量

原理:屏蔽中断的软件实现机制。

假定一个共享(锁)变量,初值为0。代表临界区内无进程,进程进入临

界区后将其改变为1,代表临界区内有进程;倘若进程在进入临界区之前。

锁变量值为1。该进程将等待其值变为0。

未能实现的原因:与假脱机文件夹的疏漏一样。假设一个进程进入临界区,可是在

它把锁变量置1之前被中断,还有一个进程进入临界区后将0置1,这样。

当前一个进程再次执行时它也将锁变量置1,这样临界区内依旧存在两

个进程。

(3)严格轮换

原理:共享turn变量。用来记录轮到那个进程进入临界区。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

当turn=0时,仅仅有进程0能进入临界区,进程0在离开临界区前将turn

置1。从而标志。轮到进程1进入临界区。

缺点:严格地轮换,可能导致临界区外的进程堵塞须要进入临界区的进程(例

如:当turn=0时。意味着仅仅有进程0能进入临界区,这时假设进程0还要

100年才会进入临界区,而进程1须要立即进入,那进程1还要白白等100

年.)

总结:当一个进程比还有一个进程慢了很多的情况下,不宜用这样的方式。

(4)Peterson解法

这是Peterson本人发明的一种简单的相互排斥算法。

我们分情况跑一遍程序:

a、进程0通过调用enter_region()进入临界区。此时1也想调用enter_region()

来进入临界区。但interested[0]为TRUE,因此被while循环挂起,当进程0出临

界区时调用leave_region()。将interested[0]设为FALSE,进程1就可以及时进入临界

区。

b、当进程0在调用enter_region()过程的随意时刻被中断,进程1进入临界区

后进程0再次进行时,依旧会被挂起。(实际上while循环体中的两条推断句就

保证了,当一个进程在临界区中时,还有一个想进入临界区的进程必定会被挂起)。

(5)TSL指令

原理简述:

TSL(test and set lock),是十分适合多处理器计算机实现相互排斥的硬件支持。它会

在一个进程进入临界区时。锁住内存总线,从而禁止其它CPU在本指令结束之前

訪问内存。

对于TSL指令,本文之做简单的原理性描写叙述(尽管老师上课讲的比較具体),想进

一步了解关于TSL指令,能够看一下书中本节内容,有具体阐述。

4、综述

要想拟定一个方案,使它既能避免竞争条件,又能保证进程执行与协作的效率,必需要满足4个条件。

(1)、不论什么两个进程不能同一时候处于临界区

(2)、不应对CPU的速度和数量做不论什么假定

(3)、临界区外执行的进程不能堵塞其它进程

(4)、不得使进程无限期等待进入临界区

(下图为避免竞争条件的模型图)

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

时间: 2024-10-22 18:01:50

进程间通信(一):竞争条件与相互排斥方案的相关文章

深入理解相互排斥锁的实现

在实际的软件编程中,常常会遇到资源的争用,比方以下的样例: [cpp] view plaincopyprint? class Counter { private: int value; public: Counter(int c) { value = c; } int GetAndIncrement() { int temp = value; //进入危急区 value = temp +1; //离开危急区 return value; } } class Counter { private: i

Linux多线程同步之相互排斥量和条件变量

1. 什么是相互排斥量 相互排斥量从本质上说是一把锁,在訪问共享资源前对相互排斥量进行加锁,在訪问完毕后释放相互排斥量上的锁. 对相互排斥量进行加锁以后,不论什么其它试图再次对相互排斥量加锁的线程将会被堵塞直到当前线程释放该相互排斥锁.假设释放相互排斥锁时有多个线程堵塞,所以在该相互排斥锁上的堵塞线程都会变成可进行状态.第一个变成执行状态的线程能够对相互排斥量加锁.其它线程在次被堵塞,等待下次执行状态. pthread_mutex_t 就是POSIX对于mutex的实现. 函数名 參数 说明 p

Linux 同步方法剖析--内核原子,自旋锁和相互排斥锁

在学习 Linux® 的过程中,您或许接触过并发(concurrency).临界段(critical section)和锁定,可是怎样在内核中使用这些概念呢?本文讨论了 2.6 版内核中可用的锁定机制,包含原子运算符(atomic operator).自旋锁(spinlock).读/写锁(reader/writer lock)和内核信号量(kernel semaphore). 本文还探讨了每种机制最适合应用到哪些地方.以构建安全高效的内核代码. 本文讨论了 Linux 内核中可用的大量同步或锁定

RAII手法封装相互排斥锁

CriticalSectionWrapper是一个接口类 class CriticalSectionWrapper { public: // Factory method, constructor disabled static CriticalSectionWrapper* CreateCriticalSection(); virtual ~CriticalSectionWrapper() {} // Tries to grab lock, beginning of a critical se

Linux同步与相互排斥应用(零):基础概念

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 当操作系统进入多道批处理系统时代以后.一个系统中就存在多个任务,每一个任务都依照一定的算法进行调度来使用内存.cpu等共享资源. 当当中一个任务等待其它资源时,该任务能够临时睡眠,操作系统调度另外任务继续运行额,这样能够使系统资源得到最大化利用.而无需像曾经单道批处理系统那样仅仅有当一个任务完毕之后才运行下一个任务. 可是由此也引入了多任务并发

并发编程中的竞争条件

下面关于竞争条件的描述,来自<现代操作系统> 在一些操作系统中,协作的进程可能共享一些彼此都能读写的公用存储区.这个公用存储区可能在内存中(可能是在内核数据结构中),也可能是一个共享文件.这里共享存储区的位置并不影响通信的本质及其带来的问题.为了理解实际中进程间通信如何工作,我们考虑一个简单但很普遍的例子:一个假脱机打印程序.当一个进程需要打印一个文件时,它将文件名放在一个特殊的假脱机目录 (spooler directory)下.另一个进程(打印机守护进程)则周期性地检查是否有文件需要打印,

Linux内核竞争条件漏洞-导致远程代码执行

导读 *本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担. 运行了Linux发行版的计算机设备,如果内核版本小于5.0.8的话,将有可能受到一个内核竞争条件漏洞的影响,并导致系统无法抵御远程网络攻击.潜在的攻击者可以利用Linux内核中net/rds/tcp.c的rds_tcp_kill_sock TCP/IP实现缺陷,从而触发设备的拒绝服务(DoS)状态,并在受影响的设备上实现远程代码执行.攻击者可以通过特制的TCP数据包对存在漏

线程同步与相互排斥:相互排斥锁

为什么须要相互排斥锁? 在多任务操作系统中,同一时候执行的多个任务可能都须要使用同一种资源.这个过程有点类似于,公司部门里.我在使用着打印机打印东西的同一时候(还没有打印完).别人刚好也在此刻使用打印机打印东西,假设不做不论什么处理的话,打印出来的东西肯定是错乱的. 以下我们用程序模拟一下这个过程.线程一须要打印" hello ",线程二须要打印" world ",不加不论什么处理的话.打印出来的内容会错乱: [cpp] view plaincopy #includ

一起talk C栗子吧(第一百回:C语言实例--使用信号量进行进程间同步与相互排斥一)

各位看官们.大家好,上一回中咱们说的是进程间同步与相互排斥的样例,这一回咱们说的样例是:使用信号量进行进程间同步与相互排斥. 闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,信号量是由著名计算机科学家迪杰斯特拉(Dijkstra)提出的一种概念,专门用来解决进程间同步与相互排斥.在他提出的概念中信号量是一个非负整数值. 信号量的操作仅仅能有两种原子操作: 等待信号; 发送信号. "什么是原子操作呢?"台下有看官在提问.原子操作就是指某个动作在运行时不能被其他动作中断,它会一