1、概念

1.1 进程同步与互斥

在多道程序环境下,进程是并发执行的(并发执行是指两个或多个事件在某段时间间隔内并发),不同进程之间存在着不同的相互制约关系。为了协调进程之间的相互制约关系,引入了进程同步的概念。

进程同步是直接制约关系,指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调他们的工作次序而等待、传递信息所产生的的制约关系。(源于他们之间的互相合作关系)

进程互斥是间接制约关系,当一个进程进入临界区使用临界资源时,另一个进程必须等待,当占用临界资源的进程退出临界区时,另一个进程才允许去访问此临界资源。

临界资源是一次仅允许一个进程使用的资源,临界资源的访问过程:进入区(在进入区要检查可否进入临界区,并设置正在访问临界区的标识,以阻止其他进程同时进入),临界区,退出区,剩余区

临界区是访问临界临界资源的那段代码

同步机制准则:

空闲让进:临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区

忙则等待:当已有进程进入临界区时,其他试图进入临界区的进程必须等待

有限等待:对请求访问的进程,应保证能在有限时间内进入临界区

让权等待:当进程不能进入临界区时,应立即释放处理器,防止进程忙等待

1.2 信号量

信号量是一种功能较强的机制,可以用来解决互斥与同步的问题,它只能被两个标准的原语操作,即为“P”和“V”操作,P操作是信号量减1,V操作是信号量加1

原语是指完成某种功能且不被分割、不被中断执行的操作序列

(1)整型信号量

整型信号量是来表示资源数目的整形量S,只要S≤0,就会不断测试,并未遵循“让权等待”的准则,而是使进程处于“忙等”状态。

P(S){while(S<=0){S = S-1}
}V(S){S=S+1
}

(2)记录型信号量

记录型信号量机制是一种不存在“忙等”现象的进程同步机制,除了表示资源数目的整型变量S外,再增加一个进程链表L,用于链接所有等待该资源的进程。

//定义结构体
typedef struct{int S;struct process *L;
}semaphore;void P(semaphore se){se.S--;if(se.S<0){add this process to se;block(se); //调用block原语,进行自我阻塞}
}void V(semaphore se){se.S++if (se.S<=0){remove a process P from se;wakeup(P); //调用wakeup原语,唤醒链表中的第一个等待进程}
}

(3)分析进程同步和互斥问题的方法步骤

  • 关系分析:找出问题中的进程数,并分析他们之间的同步和互斥关系
  • 整理思路:找出解决问题的关键点,并且根据做过的题目找出解决思路,根据进程的操作流程确定P操作,V操作的大致顺序
  • 设置信号量:设置需要的信号量,确定处置,完善整理

(4)利用信号量实现进程同步

问题描述:S为P1、P2两个进程的公共信号量,初始值为0,进程P2执行需要依赖进程P1中语句x的运行结果,即只有当语句x执行完成之后,语句y才可以执行。

semaphore S=0;P1(){x; //先执行xV(S);  //s++
}P2(){P(x);y ;V(y);}

(5)利用信号量实现互斥

问题描述:设S为实现进程P1、P2互斥的信号量,由于每次只允许一个进程进入临界区,设置S=1(即可用资源数为1),当进程对信号量S进行P操作后进入临界区,并在退出后,该进程对该信号量执行V操作,表示没有进程进入临界区,可以让其他进程进入。设计如下:

semaphore S=1;P1(){P(S); //访问临界资源,S--//进入临界区V(S);//访问结束,S++
}
P2(){P(S); //访问临界资源,S--//进入临界区V(S);//访问结束,S++
}

2、经典问题

2.1 生产者-消费者

  • 问题描述:一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或者一个消费者从中取出消息。
  • 问题分析:

(1)关系分析:生产者和消费者对缓冲区访问是互斥,生产者和消费者又是相互协作关系,生产者生产之后才能消费,属于同步关系

(2)整理思路:只有生产者和消费者两个进程,两个进程间存在着同步和互斥关系,要解决互斥和同步PV操作的位置

(3)信号量设置:信号量mutex作为互斥信号量,它用于控制互斥访问缓冲池,互斥信号量初值为1;信号量full用于记录当前缓冲池中“满”缓冲区数,初值为0。信号量empty 用于记录当前缓冲池中“空”缓冲区数,初值为n。

#define semaphore intsemaphore empty=n; //表示空缓冲区的个数
semaphore full=0; //表示满缓冲区的个数semaphore mutex =1; //互斥信号量(生产者和消费者共用缓冲区)void Producer(){while(1) {produce a item; //生产数据P(empty); //空缓冲区的个数减1P(mutex); //互斥变量减1,进入临界区add  item to buffer; // 将item放入缓冲区V(mutex);  //互斥量加1,退出临界区V(full);   //满缓冲区加1}
}
void Consumer(){P(full); // 同步,判断缓冲区是否有生产者P(mutex); //互斥变量减1,进入临界区remove item from buffer; //将item移除缓冲区V(mutex); //互斥量加1,退出临界区V(empty); //空缓冲区加1consumer a item; //消费数据
}

2.2 分水果问题

  • 问题描述:桌子上有一个盘子,每次只能想其中放入一个水果,爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果。只有盘子为空时,爸爸或妈妈就可向盘子中放一个水果;仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出。
  • 问题分析:

(1)关系分析。这里的关系稍复杂一些,首先由每次只能向其中放入一只水果可知爸爸和妈妈是互斥关系。爸爸和女儿、妈妈和儿子是同步关系,而且这两对进程必须连起来,儿子和女儿之间没有互斥和同步关系,因为他们是选择条件执行,不可能并发

(2)整理思路。这里有4个进程,实际上可以抽象为两个生产者和两个消费者被连接到大小为1的缓冲区上

(3) 信号量设置。首先设置信号量plate为互斥信号量,表示是否允许向盘子放入水果,初值为1,表示允许放入,且只允许放入一个。信号量 apple表示盘子中是否有苹果,初值为0,表示盘子为空,不许取,若apple=1可以取。信号量orange表示盘子中是否有橘子,初值为0,表示盘子为空,不许取,若orange=1可以取。

notes:生产者和消费者是生产者生产完把缓冲区释放,消费者再去访问缓冲区;分水果是放完水果,标记盘子有水果,才会去拿水果,再释放盘子。

#define semaphore int
semaphore plate=1;  //互斥
semaphore apple=0;
semaphore orange=0;void dad(){while(1){//prepare an appleP(plate);put the apple on the plate;V(apple);  //apple标记为1,证明盘子有apple}
}void mom(){while(1){//prepare an orangeP(plate);put the orange on the plate;V(orange);  //orange标记为1,证明盘子有orange}
}void daughter(){while(1){P(apple) take an apple from the plate;V(plate);  //plate标记为1,证明可以放水果了eat the apple;}
}void son(){while(1){P(orange) take an orange from the plate;V(plate);  //plate标记为1,证明可以放水果了eat the orange;}
}

2.3 读者和写者问题

  • 问题描述:有读者和写者两组并发进程,共享一个文件,当两个或以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。因此要求:①允许多个读者可以同时对文件执行读操作;②只允许一个写者往文件中写信息;③任一写者在完成写操作之前不允许其他读者或写者工作;④写者执行写操作前,应让已有的读者和写者全部退出。
  • 问题分析

(1)关系分析:有两个进程:读者进程和写者进程,写者和读者、写者和写者都是互斥的,读者和读者是同步关系(依次访问,依次退出),可以同时有多个读者在读

(2)整理思路:写者是跟任何进程互斥,用PV可以解决,读者比较复杂,除了实现与写者的互斥,还要实现与其他读者的同步,设计了一个计数器来判断当前是否有读者读文件,同时,不同读者对计数器的访问也应该是互斥的

(3)信号量设置:首先设置信号量count为计数器,用来记录当前读者数量,初值为0; 设置rmutex为互斥信号量,用于保护更新count变量时的互斥;设置互斥信号量rw用于保证读者和写者的互斥访问。

#define semaphore int
semaphore rmutex=1; //读者之间(依次访问和退出)的互斥量
semaphore wmutex=1; //写者和读者的互斥量
int count=0; //统计读者的数量void reader(){while(1){P(rmutex)if(count==0) P(wmutex); //count==0 意味着没有读者在读文件,可以写文件,先进行加锁count++;V(rmutex)reading; //读者进入之后,进行写文件P(mutex);count--;if(count==0)V(wmutex); //count==0证明读者已经读完退出文件,可以写,并将互斥量解锁V(rmutex); //释放互斥变量}
}void writer(){while(1){P(wmutex);writing;V(wmutex);}
}

2.4 哲学家进餐(死锁)

  • 问题描述:一张圆桌上坐着5名哲学家,每两个哲学家之间的桌上摆一根筷子,桌子的中间是一碗米饭,如图2-10所示。哲学家们倾注毕生精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿的时候,才试图拿起左、 右两根筷子(一根一根地拿起)。如果筷子已在他人手上,则需等待。饥饿的哲学家只有同时拿到了两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考。
  • 补充:饥饿和死锁的定义

“饥饿”并不表示系统一定死锁,但至少有一个进程的执行被无限期推迟。“饥饿”与死锁的主要差别有:

(1)进入“饥饿”状态的进程可以只有一个,而由于循环等待条件而进入死锁状态的进程却必须大于或等于两个。

(2)处于“饥饿”状态的进程可以是一个就绪进程,如静态优先权调度算法时的低优先权进程,而处于死锁状态的进程则必定是阻塞进程。

  • 问题分析:

(1)关系分析:5个哲学家和左右邻居对其中间的筷子访问是互斥关系

(2)整理思路:本题的关键是如何让一个哲学家拿到左右两个筷子而不造成死锁或者饥饿现象。那么解决方法有两个,一个是让他们同时拿两个筷子;二是对每个哲学家的动作制定规则,避免饥饿或者死锁现象的发生。

(3)信号量设置:定义互斥信号量数组chopstick[5] = {l, 1, 1, 1, 1}用于对5个筷子的互斥访问。对哲学家按顺序从0~4编号,哲学家i左边的筷子编号为i,哲学家右边的筷子编号(i+1)%5。(同时拿两边的筷子)

#define semaphore int
semaphore chopstick[5]={1,1,1,1,1}Pi(){while(1){P(chopstick[i]);  //拿左筷子P(chopstick[(i+1)%5]);   //拿右筷子eat; //进餐V(chopstick[i]);  //放下左筷子V(chopstick[(i+1)%5]);   //放下右筷子think; //思考}}

该算法存在以下问题:当五个哲学家都想要进餐,分别拿起他们左边筷子的时候(都恰好执行完P(chopstick[i]);)筷子已经被拿光了,等到他们再想拿右边的筷子的时候(执行 P(chopstick[(i+l)%5]);)就全被阻塞了,这就出现了死锁。

为了防止死锁的发生,可以对哲学家进程施加一些限制条件,比如至多允许四个哲学家同时进餐;仅当一个哲学家左右两边的筷子都可用时才允许他抓起筷子;对哲学家顺序编号,要求奇数号哲学家先抓左边的筷子,然后再转他右边的筷子,而偶数号哲学家刚好相反。正解制定规则如下:假设釆用第二种方法,当一个哲学家左右两边的筷子都可用时,才允许他抓起筷子。

semaphore chopstick[5] = {1,1,1,1,1}; //初始化信号量
semaphore mutex=l;  //设置取筷子的信号量
Pi(){ //i号哲学家的进程while(1){P (mutex) ; //在取筷子前获得互斥量P (chopstick [i]) ; //取左边筷子P (chopstick[ (i+1) %5]) ;  //取右边筷子V (mutex) ; //释放取筷子的信号量eat;  //进餐V(chopstick[i] ) ;  //放回左边筷子V(chopstick[ (i+l)%5]) ;  //放回右边筷子think;  // 思考}
}

参考内容:

信号量:整型、记录型信号量以及利用信号量实现进程互斥和前驱关系_C语言中文网

操作系统——经典同步问题相关推荐

  1. 操作系统 --经典同步问题之吸烟者问题读者-写者问题(七)

    一.吸烟者问题 1.问题描述 假设一个系统有三个抽烟者进程和一个供应者进程.每个抽烟者不停地卷烟并抽掉,但是要卷起并抽掉一支烟,需要三种材料:烟草.纸.胶水.三个抽烟者中,每一个第一个拥有烟草,第二个 ...

  2. 操作系统-经典同步例题

    目录 1. 生产者/消费者问题 2. 读者和写者问题 3. 理发师睡觉问题 1. 生产者/消费者问题 描述: 一个或多个生产者产生数据并放入缓冲 每次只能有一个消费者从缓冲区取数据(互斥) 每次只能由 ...

  3. (王道408考研操作系统)第二章进程管理-第三节10:经典同步问题之哲学家进餐问题

    本文接: (王道408考研操作系统)第二章进程管理-第三节6:经典同步问题之生产者与消费者问题 ((王道408考研操作系统)第二章进程管理-第三节7:经典同步问题之多生产者与多消费者问题 (王道408 ...

  4. (王道408考研操作系统)第二章进程管理-第三节8:经典同步问题之吸烟者问题

    本文接: (王道408考研操作系统)第二章进程管理-第三节6:经典同步问题之生产者与消费者问题 ((王道408考研操作系统)第二章进程管理-第三节7:经典同步问题之多生产者与多消费者问题 文章目录 一 ...

  5. (王道408考研操作系统)第二章进程管理-第三节7:经典同步问题之多生产者与多消费者问题

    注意:生产者与消费者问题Linux系统编程专栏有案例讲解 Linux系统编程39:多线程之基于阻塞队列生产者与消费者模型 Linux系统编程40:多线程之基于环形队列的生产者与消费者模型 本文接:(王 ...

  6. 【操作系统】信号量解决经典同步问题

    文章目录 1. 基本结构 2. P,V操作 3. 信号量的应用 3.1 信号量实现进程互斥 3.2 信号量实现前驱关系 4. 用信号量解经典同步问题 4.1 生产者消费者问题 4.2 读者写者问题 4 ...

  7. 【操作系统/OS笔记14】经典同步问题:读者-写者问题、哲学家就餐问题

    本次笔记内容: 10.6 经典同步问题-1 10.7 经典同步问题-2 10.8 经典同步问题-3 10.9 经典同步问题-4 10.10 经典同步问题-5 10.11 经典同步问题-6 文章目录 读 ...

  8. 写出记录型信号量中的wait操作代码_操作系统进程的同步与互斥及经典同步与互斥问题...

    概览 临界区临界区的引入 在系统当中,有些资源允许多个进程共享(磁盘),有些资源只允许进程单独使用(打印机,共享变量).为了让进程单独使用资源而不受其他进程干扰引入了临界区的概念. 临界区的概念 在一 ...

  9. 经典同步问题三——读者写者问题

    系列同步问题: 经典同步问题一--生产者和消费者问题 https://blog.csdn.net/weixin_36465540/article/details/105560002 经典同步问题二-- ...

  10. 经典同步问题二——哲学家进餐问题

    系列同步问题: 经典同步问题一--生产者和消费者问题 https://blog.csdn.net/weixin_36465540/article/details/105560002 经典同步问题二-- ...

最新文章

  1. 数位dp ---- 暴力 + 二进制的数位dp 2020济南 L Bit Sequence
  2. 史上最全DSO学习资料
  3. Gartner:解开关于人工智能的六个迷思
  4. linux修改mysql默认大小写配置,linux下设置mysql不区分大小写
  5. Eclipse/MyEclipse安装FindBugs
  6. ​​使用win7超级终端连接华为交换机并配置端口镜像
  7. 庆祝教师节,李宁老师课程优惠劵疯抢中、会员卡优惠中,先到先得
  8. SAP MM模块-实施顾问岗位-面试手册-项目管理经验面试清单-英文
  9. c语言年历表程序设计,c语言程序设计年历显示-20210413153548.docx-原创力文档
  10. Mysql(2)_ binlog文件
  11. 视频去模糊论文阅读-Cascaded Deep Video Deblurring Using Temporal Sharpness Prior
  12. 小乔皮肤分析-缤纷独角兽/青蛇皮肤
  13. 【统计信号处理检测理论:CFAR检测】
  14. 我是如何次次《头脑王者》获得满分的
  15. 愿你与生活交手多年,依然满怀新鲜,
  16. Bootstrap学习
  17. 你需要了解的JS框架
  18. 免费滴永恒G,试试无妨
  19. EHR_ERAL_KAYANG店铺提点方案相关函数
  20. 谁抢走你的棒棒糖?精彩的创意让你得到的不仅仅是震撼 值得一看(图)

热门文章

  1. XTU 1336 Perfect Palindrome Number
  2. gh-ost在线主从同步MySQL下DDL生产表结构修改(初步研究)
  3. 个推大数据:3月线上消费率先恢复,在线购物APP迎来春天
  4. 如何构建健商品期carry组合
  5. 阿里面试整个流程(已OC)
  6. xbee模块和单片机_什么是xbee模块?和zigbee模块有什么区别?
  7. JAVA空间换时间以及时间换空间的例子
  8. vue 倒计时 插件_vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
  9. Unity 接入 ILRuntime 热更方案
  10. off-by-one