170323进程与线程-2 进程间通信 信号量PV 互斥量 忙等待等
一.进程间通信
1.1 三个问题-IPC问题(Inter Process Communication)进程间通信
(1)进程间消息的传递
①一个进程如何把信息传递给另一个。
②管道(pipeline)
(2)进程互斥(mutual exclusion)(mutex互斥体,计算机术语)
确保两个或更多的进程在关键活动中不会出现交叉。如不同的用户试图争夺飞机上最后一个座位。
(3)进程同步
与正确的顺序有关。如进程A产生数据而进程B打印数据,那么B的操作必须等待A产生数据。
适用于“线程”
“消息传递”对处同一进程的线程较简单;不同进程的线程通信属于进程间的通信
(4)示例:交通流量统计
(5)示例:两个进程同时想访问共享内存
1.2 竞争条件
(1)竞争条件(race condition)
①两个或多个进程读写某些共享数据,而最后的结果取决于精确时序。
②调试(测试)包含竞争条件的程序是一件非常困难的事。大多数的测试结果都很好,但在极少数情况下会发生一些无法解释的奇怪现象。
③与时间有关的错误
·在相同的前提条件下,两次执行的结果有可能不相同。在操作系统里,把这种由于时间因素的影响而产生的错误,称为“与时间有关的错误”。
(2)原语(primitives)
(进程)一旦启动就要保证做完,中间不能插入其他程序的执行序列。整体出现,不可分割。
(3)临界区(critical region,critical section)
对共享内存等资源进行访问的程序片。
1.3 临界区(critical region,criticalsection)
(1)假设某个系统有n个进程,每个进程有一个代码段(临界区),在该区中进程可能改变共同变量、更新一个表、写一个文件等。
(2)临界区问题的解答须满足三项要求
①互斥(mutual exclusion):最多只能一个进程在临界区内执行
②前进:如果没有进程在临界区中,那么在等待进入临界区的进程中确定下一个进入的进程,这个选择不能无限推迟。
③有限等待:从一个进程做出进入临界区的请求,直到允许,其他进程允许进入临界区的次数有上限。
(3)操作系统内的临界区问题:抢占内核与非抢占内核
①抢占内核:允许处于内核模式的进程被抢占。
②非抢占内核:不允许被抢占。
③Windows XP与Windows 2000:非抢占内核。
④传统UNIX:非抢占内核。
⑤Linux:2.6以前为非抢占内核;2.6变为抢占内核。
⑥其他UNIX(Solaris与IRIX):抢占内核。
(4)解决竞争条件方案满足的4条件----引自AST P67
①任何两个进程不能同时处于其临界区
②不应对CPU的速度和数量做任何假设
③临界区外运行的进程不得阻塞其他进程
④不得使进程无限期等待进入临界区
二.信号量上的P、V操作
2.1(1)示例:双轨转单轨(临界区及信号量)
(2)信号量引自《现代操作系统》P72
①Edsger Wybe Dijkstra (1930-2002),荷兰人。1965年提出
②荷兰语中,Proberen的意思是尝试/测试,Verhogen的含义是增加或升高。
③P和V操作必须是原子操作,或原语
④原子操作:是指一组相关联的操作要么都不间断地执行,要么都不执行。原子操作在计算机科学的其他领域也是非常重要的。
(3)信号量上的P、V操作算法
①设置信号量初值Vs
②P操作(down):申请进入临界区
·Vs=Vs-1
·判断Vs>=0
TRUE:继续(执行临界区命令)
FALSE:阻塞
③V操作(up):退出临界区
·Vs=Vs+1
·判断Vs>0
TRUE:继续(执行临界区后命令)
FALSE:唤醒Vs上阻塞的进程,再执行临界区后命令。
(4)算法实例:两个进程同时想访问共享内存
(5)进程同步:GET与COPY
信号量解决进程同步:
进程同步:GET与COPY,PV操作
semaphore s1=0 semaphore s2=0 void main(){ cobegin { 进程“GET” while(TRUE) { 从文件F取一个记录送至输入缓冲区R; V(S1); //为COPY发已完成读取一个记录消息 P(S2); //等待COPY发停车消息 } 进程“COPY” while(TRUE) { P(S1): 等待COPY发完成消息 将R中的记录拷贝到T中 V(S2):向GET发已完成COPY消息 } } coend }
(6)示例:两组交替投球 引自宗大华〈操作系统(第二版)习题集
有A、B两组学生进行投球比赛,规则是:A组学生先投掷,然后两组交替投掷。试用信号量上的P、V操作管理这项比赛工作,并给简略示意图。
(7)示例:盘中水果放取 引自宗大华〈操作系统(第二版)习题集
一只盘子里只能放一个水果,爸爸往里面放苹果妈妈往里面放橘子,儿子专等吃橘子,女儿专等吃苹果。只要盘子空,爸爸或妈妈就可以往里面放水果;仅当盘子里有自己需要的水果时,儿子或女儿才可以取出吃。把爸爸、妈妈、儿子和女儿看作4个进程,用信号量上的P、V操作来管理他们的并发执行.
2.2互斥量(Mutexes)(《现代操作系统》P74)
(1)信号量的一个简化版本(不需要信号量的计数能力)。
(2)互斥量仅适用于管理共享资源或一小段代码。由于互斥量在实现时既容易又有效,这使得互斥量在实现用户空间线程包时非常有用。
(3)互斥量是一个可以处于两态之一的变量:
①解锁(unlocked):整型量0
②加锁(locked):其他非0
(4)当一个线程(或进程)需要访问临界区时,它调用mutex_lock。
①如果互斥量当前是解锁的(临界区可用),此调用成功,并进入临界区。
②如果互斥量已经加锁,调用线程被阻塞,直到在临界区中的线程完成并调用mutex_unlock。如果多个线程被阻塞在该互斥量上,将随机选择一个线程并允许它获得锁。
(5)用于用户级线程包的代码见下图
由于thread_yield只是在用户空间中对线程调度程序的一个调用,所以运行快捷。这样mutex_lock和mutex_unlock都不需要任何内核调用。
2.3 PTHREAD
引自《Pthread百度百科》http://baike.baidu.com/view/974776.htm;《现代操作系统》P75
(1)POSⅨ thread 简称为pthread,Posix线程是一个POSⅨ 标准线程.该标准定义内部API创建和操纵线程。
(2)最常用的POSⅨ 系统如Linux和Unix,而微软的Windowsimplementations同时存在.举例来说,pthreads-w32可支持MIDP的pthread
(3)Pthreads定义了一套C程序语言类型、函数与常量,它以pthread.h 头文件和一个线程库实现。
(4)与互斥量相关的pthread见下图。
(5)条件变量:且于同步。允许线程由于一些未达到的条件而阻塞。相关的phread调用见下图。
2.4忙等待的互斥
(1)屏蔽中断法
不好。屏蔽中断的权力交给用户进程。
(2)锁变量
共享(锁)变量(0-解锁,1-加锁)。对锁的并发操作可能引起别的竞争条件。
(3)严格轮转法
采用忙等待(自旋锁)。turn初值为0,轮流进入临界区。当一个较另一个快很多时,被临界区外的阻塞。
(4)Peterson解法
1981,G.L.Peterson
(5)TSL指令
测试并加锁(Test and Set Lock)
第
(6)示例:严格轮换法
(7)示例:Peterson解法
2.5睡眠与唤醒
忙等待互斥方案的问题
想进入但不能进入临界区的进程处于“就绪”态。
下述方案当将不能进入临界区的进程置于“阻塞”态。并使用进程通信原语。
(1)生产者—消费者问题(producer—consumer)
①也称有界缓冲区(bounder-buffer)问题
②两个进程共享一个公共的固定大小的缓冲区
③其中一个是生产者,将信息放入缓冲区;
④另一个是消费者,从缓冲区中取出信息。
⑤缓冲区满时,生产者睡眠,并等待消费者唤醒;
⑥缓冲区空时,消费者睡眠,并等待生产者唤醒。
⑦也存在竞争条件。有一个公共变量count用于统计缓冲区的数据项数量。
(2)信号量上的PV操作
①E.W.Dijkstra在1965年提出。
②信号量(semaphore)、down(P操作,Proberen尝试)、up(V操作,Verhogen增加或升高)。解决丢失的Wakeup问题
③Mutex(互斥量,互斥体):处于两态之一的变量。0解锁,其它加锁。访问临界区时调用Mutex_lock,离开Mutex_unlock