阅读本篇之前推荐阅读以下姊妹篇:

秒杀多线程第四篇一个经典的多线程同步问题

秒杀多线程第五篇经典线程同步关键段CS

秒杀多线程第六篇经典线程同步事件Event

秒杀多线程第七篇经典线程同步互斥量Mutex

秒杀多线程第八篇经典线程同步信号量Semaphore

秒杀多线程第九篇经典线程同步总结关键段事件互斥量信号量

秒杀多线程第十篇生产者消费者问题

秒杀多线程第十一篇读者写者问题

上面的文章讲解了在Windows系统下实现多线程同步互斥的方法,为了提高在实际问题中分析和思考多个线程之间同步互斥问题的能力,接下来将讲解PV操作,这也是操作系统中的重点和难点。本文将会先简要介绍下PV操作的来源和基本使用方法,然后再通过两道经典的计算机考研真题——放水果和安全岛来示范如何运用PV操作。

先讲讲PV操作的起源和用法。

1962年,荷兰学者Dijksrta在参与X8计算机的开发中设计并实现了具有多道程序运行能力的操作系统——THE Multiprogramming System。为了解决这个操作系统中进程(线程)的同步与互斥问题,他巧妙地利用火车运行控制系统中的“信号灯”(semaphore,或叫“信号量”)概念加以解决。信号量的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,这个信号量的值仅能由PV操作来改变。

PV操作由P操作原语和V操作原语组成(原语也叫原子操作Atomic Operation,是不可中断的过程),对信号量(注意不要和Windows中的信号量机制相混淆)进行操作,具体定义如下:

P(S):

①将信号量S的值减1,即S=S-1;

②如果S>=0,则该进程继续执行;否则该进程置为等待状态。

V(S):

①将信号量S的值加1,即S=S+1;

②该进程继续执行;如果该信号的等待队列中有等待进程就唤醒一等待进程。

用PV操作实现多线程的同步与互斥是非常简单的,只要考虑逻辑处理上合理严密而不用考虑具体技术细节,因此与写伪代码较为相似。比如有多个进程P1、P2、 ……PN。它们要互斥的访问一个资源。用PV操作来实现就非常方便直观。下面是PV操作代码:

设置信号量为S,初值为1。各进程的操作流程如下:

进程P1              进程P2           ……          进程Pn

P(S);              P(S);                           P(S);

访问资源;         访问资源;                      访问资源;

V(S);             V(S);                          V(S);

可以看出PV操作会忽略具体的编程细节,让程序员的主要精力放在线程同步互斥的逻辑处理上。因此,通过练习PV操作能快速有效提高程序员对多线程的逻辑思维能力,达到强化“内功”的目的

接下来就来几道简单的计算机考研真题。

第一题 放水果 南京大学计算机考研真题

桌上有一空盘,允许存放一只水果。爸爸可向盘中放苹果,也可向盘中放桔子,儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时一次只能放一只水果供吃者取用,请用P、V原语实现爸爸、儿子、女儿三个并发进程的同步。

这个题目涉及的东西非常之多,光人物就有三个再加水果,盘子等等,确实让人感觉好像无从下手。但不管题目如何变,只要牢牢的抓住同步和互斥来分析问题就必定能迎刃而解。

下面先考虑同步情况即所有“等待”情况:

第一.爸爸要等待盘子为空。

第二.儿子要等待盘中水果是桔子。

第三.女儿要等待盘中水果是苹果。

接下来来考虑要互斥处理的资源,看起来盘子好像是要作互斥处理的,但由于题目中的爸爸、儿子、女儿均只有一个,并且他们访问盘子的条件都不一样,所以他们根本不会同时去访问盘子,因此盘子也就不用作互斥处理了。分析至些,这个题目已经没有难度了,下面用PV原语给出答案:

先设置三个信号量,信号量Orange表示盘中有桔子,初值为0。信号量Apple表示盘中有苹果,初值为0。信号量EmptyDish表示盘子为空,初值为1。三个人的操作流程如下所示:

1.爸爸

P(EmptyDish)

if (rand()%2==0)

{

放桔子

V(Orange)

}

else

{

放苹果

V(Apple)

}

2.儿子

P(Orange)

取桔子

V(EmptyDish)

3.女儿

P(Apple)

取苹果

V(EmptyDish)

第二题 安全岛 南开大学考研真题

在南开大学至天津大学间有一条弯曲的路,每次只允许一辆自行车通过,但中间有小的安全岛M(同时允许两辆车),可供两辆车在已进入两端小车错车,设计算法并使用P,V实现。

这个问题应该如何考虑了?同样只要牢牢的抓住同步和互斥来分析问题就必定能迎刃而解。

考虑所有“等待”情况:

在路口N准备从N到T的人应该什么时候进入了?如果他只判断道路K上有没有人肯定是不行的,因为如果安全岛M上已经有2个人,那么路口N和路口T再各进一人,肯定会造成死锁。因此可以这样——在路口N准备从N到T的人要等待与他同方向的人已经到达T,如果此人已经到达T,且道路K上没有人,他必定可以上路了。同理在路口T准备从T到N的人也应该这样做。

再考虑互斥情况:

路上每次只允许一辆自行车通过,所以道路是需要作互斥处理的。

分析之后,下面就用PV原语给出答案(考研辅导书上的答案):

设置信号量NT表示在路口N且从N到T方向上允许出发的自行车数量,初值为1。信号量TN表示在路口T且从T到N方向上允许出发的自行车数量,初值为1。信号量K和L表示道路,初值均为1。这样从N到T的车和从T到N的车的行驶流程如下:

从N到T的车                     从T到N的车

P(NT)                P(TN)

P(K)                 P(L)

由N到M               由T到M

V(K)                 V(L)

P(L)                 P(K)

由M到T               由M到T

V(L)                 V(K)

V(NT)                V(TN)

这个题目的解法有很多,比如还可以用信号量M来记录安全岛M上空位个数,初值为2。每个进入道路前的人都要先预订安全岛上的空位,订到后再互斥的进入道路。否则就要等待安全岛上有空位。信号量K和L表示道路,初值均为1。然后从N到T的车和从T到N的车的行驶流程如下:

从N到T的车                     从T到N的车

P(M)                 P(M)

P(K)                 P(L)

由N到M               由T到M

V(K)                 V(L)

P(L)                 P(K)

V(M)                 V(M)

由M到T               由M到T

V(L)                 V(K)

这种解决方法也是不会造成死锁的。安全岛的解法非常之多,网上还有不少不同的解法,有兴趣的童鞋可以搜索一下。

下一篇《秒杀多线程第十三篇多线程同步内功心法——PV操作下》将讲解更难的一道PV操作题,欢迎大家参阅。

转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/7650470

多线程同步内功心法——PV操作上(未完待续。。。)的更多相关文章

  1. 多线程面试题系列(12):多线程同步内功心法——PV操作上

    上面的文章讲解了在Windows系统下实现多线程同步互斥的方法,为了提高在实际问题中分析和思考多个线程之间同步互斥问题的能力,接下来将讲解PV操作,这也是操作系统中的重点和难点.本文将会先简要介绍下P ...

  2. 转---秒杀多线程第十二篇 多线程同步内功心法——PV操作上 (续)

    PV操作的核心就是 PV操作可以同时起到同步与互斥的作用. 1.同步就是通过P操作获取信号量,V操作释放信号量来进行. 2.互斥其实就是,同时操作P操作,结束后进行V操作即可做到. Java上实现PV ...

  3. 命令行操作mysql 未完待续......

    复制数据表 create table 新表 like 旧表: 删除表中某个字段 alter table 表名 drop column 字段; 例子: alter table news_apply_lo ...

  4. [多线程同步练习]PV操作

    看一个较为复杂的生产者-消费者问题: 问题描述 桌子上有一只盘子,每次只能向其中放入一个水果.爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果.只有盘子为空时 ...

  5. Oracle表操作 (未完待续)

    1. Oracle 中将一个表中数据导入到另外一个表的方法 insert into scd_data_201007 select * from analog_data_201007 ; 2. 纵表转换 ...

  6. Python语言基础与应用 (P23)上机练习:容器类型操作(未完待续)

    上机练习:容器类型操作〉 列表.元组基本操作+, *, len(), [], in Python 3.7.0 (default, Jun 28 2018, 08:04:48) [MSC v.1912 ...

  7. Spring MVC-从零开始-文件上传(未完待续)

    Spring MVC-从零开始-文件上传(未完待续)

  8. 【av68676164(p25-p30)】同步和P-V操作

    4.5 同步和P-V操作 4.5.1 同步和互斥的概念 进程的互斥关系 例子 进程的互斥关系 多个进程由于共享了独占性资源,必须协调个进程对资源的存取顺序:确保没有两个或以上的进程同时进行存取操作. ...

  9. Java开发中的23+2种设计模式学习个人笔记(未完待续)

    注:个人笔记 一.设计模式分三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模 ...

随机推荐

  1. Android_程序结构分析

    一.Android程序运行过程 二.Android项目结构  

  2. Sqlserver_In、exists使用

    in是把外表和内表作hash 连接,而exists 是对外表作loop 循环,每次loop 循环再对内表进行查询. 一直以来认为exists 比in 效率高的说法是不准确的.如果查询的两个表大小相当, ...

  3. SAM格式 及 比对工具之 samtools 使用方法

    参考资料: SAMtools(官网) SAM Spec v1.4 (SAM格式 说明书) (重要) samtools-1.3.1 使用手册 (SAMtools软件说明书) samtools常用命令详解 ...

  4. 再说TCP神奇的40ms

    版权声明:本文由安斌原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/186 来源:腾云阁 https://www.qclou ...

  5. ExpandableListView getChildView 不执行,不显示子列表

    原因很简单: 在 GroupView 里面不要加入 button 等可点击空间,否则 和 点击 Groupview 展开相冲突. 去掉就好了getGroupView

  6. hdu----(5023)A Corrupt Mayor's Performance Art(线段树区间更新以及区间查询)

    A Corrupt Mayor's Performance Art Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100 ...

  7. 190. Reverse Bits -- 按位反转

    Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...

  8. PowerDesigner生成SQL脚本时,对象带有双引号的问题解决

    在pdm查看脚本时,发现表名和字段名带有双引号: 1.create table"cfg_user_card_account"  ( 2.  "user_card_acco ...

  9. 判断jQuery元素是否隐藏

    第一种:使用CSS属性 复制代码 代码如下: var display =$('#id').css('display'); if(display == 'none'){    alert("被 ...

  10. 15个让人惊讶的 CSS3 动画效果演示

    CSS 是网页设计非常重要的一部分,随着越来越多的浏览器对 CSS3 支持的不断完善,设计师和开发者们有了更多的选择.如今,用纯 CSS 就可以实现各种各样很酷的效果,甚至是动画. 本文收集了15个惊 ...