【操作系统】第二章 进程管理2

1.经典同步问题
(1)生产者与消费者问题
buffer: array [ 0, …, n-1] of item;
in, out: integer :=0, 0;
Var mutex, empty, full: semaphore :=1, n, 0;
producer :
repeat

produce an item in nexp;

wait(empty);//表示缓冲池中空缓冲池的数量,当empty>0时,生产者申请mutex,执行下面的操作,释放mutex后,下一个生产者才能进行。如果空缓冲池的数量为0,生产者不能再放产品,,被阻塞,等待消费者取后,才有可能抢到资源然后执行。
wait(mutex);///互斥信号量mutex,保证生产者,消费者对缓冲池的互斥使用,与wait(empty)顺序不可颠倒
buffer(in):=nexp;
in:=(in+1) mod n;
signal(mutex);
signal(full);//full表示满缓冲池的数量,empty与full在值等于0的点上是控制顺序的关键
until false;

consumer :
repeat
wait(full);//当full为0时,,没有产品。消费者取得时候,full=-1,被阻塞,只有等生产者放入产品后,才能取
wait(mutex);
nextc:=buffer(out);
out:=(out+1) mod n;
signal(mutex);
signal(empty);
consume the item in nexc;
until false;

(2)哲学家进餐问题
1)记录型信号量解决哲学家进餐问题
只有拿到两根筷子才能进餐,不可能五个人同时进餐。如果每个人都同时拿起左边的筷子,再拿右筷子时就会发生死锁。
解决方法:
至多只允许有四位哲学家同时去拿左边的筷子
semaphore chopstick[5]={1,1,1,1,1};
semahpore eat=4;//计数控制
do{
wait(eat);
wait(chopstick[ i ]);
wait(chopstick[ ( i +1) mod 5] );

 eat;
 …
      signal(chopstick[ i ]);
      signal(chopstick[ ( i +1) mod 5] );
      signal(eat);
 …
 think;}while(true)

仅当哲学家的左右筷子均可用时,才允许他拿起筷子进餐。

规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;偶数号哲学家则相反。保证总会有一个哲学家能同时获得两只筷子而进餐。
2)利用AND信号量机制解决哲学家进餐问题
semaphore chopstick[5]={1,1,1,1,1};
do{

think

Swait(chopstick[(i+1)%5],chopstick[i]);

eat

Singal(chopstick[(i+1)%5],chopstick[i]);
}while[true];
(3)读者写者问题
//读者优先 :若读者先占有互斥信号量,只有最后一个读者离开,计数降为0时才释放信号量,导致写者弱势
semaphore rmutex=1,wmutex=1;
int readcount=0;
void reader(){
do{
wait(rmutex); //读者之间的互斥信号量,使第一个读者进来竞争资源,其余读者会阻塞
if(readcount0) wait(wmutex);//判断是否为第一人,如果是,与写者竞争(读者与写者之间的互斥)
readcount++;
signal(rmutex);

perform read operation;

wait(rmutex);
readcount–;
if(readcount
0) signal(wmutex);
signal(rmutex);
}while(true);
}
void Writer()
{
do{
wait(wmutex);
perform write operation;
signal(wmutex);
}while(true);
}
void main()
{
cobegin
Reader();
Writer();
coend;
}
//写者优先 写者先占有某信号后,直到最后一个写者走完才释放该信号,读者才能进入
semaphore s=1,rmutex=1,mutex=1;
readcount=0;
writecount=0;
//互斥信号量S,读者和写者都争抢该信号;第1个写者申请S,其他写者不需要申请S;最后一个写者离开时才释放信号量S.一旦写者先申请到了S,则所有的读者只能等待写者都走完才可进入共享读。而多个写者通过S后,仍要争抢wmutex信号以完成互斥的写入

读者:
wait(s);
wait(rmutex);
if Readcount=0 then wait(wmutex);
Readcount +1;
signal(rmutex);
signal(s)
读操作
wait(rmutex);
Readcount -1;
if Readcount=0 then signal(wmutex);
signal(rmutex)

写者:
wait(mutex);
if writecount=0 then wait(s);
writecount+1;
signal(mutex);
wait(wmutex);
写入文件;
signal(wmutex);
wait(mutex);
writecount-1;
if writecount=0 then signal(s);
signal(mutex);
(4)黑白棋子问题
两个人下棋,一方执黑棋,一方执白棋。要求双方轮流下子。给出两种情况的解决办法:
1)执黑子一方先下
seamphore bfg=1,wfg=0;
void main()
{
black();
write();
}
void black()
{
while(true){
wait(bfg);
if whereput()
{
put a black qizi;
signal(wfg);
}else
{
signal(wfg);
break;
}
}
void white()
{
while(true){
wait(wfg);
put a white qizi;
signal(bfg);
}
}
2)双方都可以先下,谁先抢到棋盘谁先下。然后开始轮流下子。
seamphore bfg=1,wfg=0,m=1;
boolean fg=F;
void main()
{
black();
write();
}
void black()
{
wait(m);
if(!fg)
{
bfg=1;wfg=0;fg=T;
}
signal(m);
while(true){
wait(bfg);
if whereput()
{
put a black qizi;
signal(wfg);
}else
{
signal(wfg);
break;
}
}
void white()
{
wait(m);
if(!fg)
{
bfg=0;wfg=1;
fg=T;
}
signal(m);
while(true){
wait(wfg);
put a white qizi;
signal(bfg);
}
}
2.管程(monitor)机制
(1)需要封装:
多进程需访问的变量
对变量做的操作
(2)管程的组成
一组局部变量
对局部变量操作的一组过程
对局部变量进行初始化的语句
(3)管程特点
任何进程只能通过调用管程提供的过程入口才能进入管程访问共享数据;
任何时刻,仅允许一个进程在管程中执行某个内部过程。
(4)管程如何实现同步
对共享变量互斥操作:
管程的特点直接实现了该要求,进程一次一个进入管程调用内部过程操作共享变量。
管程的互斥访问完全由编译程序在编译时自动添上,无须程序员关心,能保证正确。
操作的同步控制:
靠条件变量的操作管理实现。
进入管程但不能获取资源操作的过程将阻塞,并在满足条件时被唤醒执行。
3.进程通信的类型
(1)高级通信机制可归结为四大类
a.共享存储器系统(操作存储区方式)
相互通信的进程共享某些数据结构或共享存储区,进程之间能够通过这些空间进行通信。
基于共享数据结构的通信方式(低级)
基于共享存储区的通信方式(高级)

b.消息传递系统(发–收方式)
c.管道通信(中间文件方式)
d.Client-Server system
(2)消息传递通信的实现方法
1)直接通信方式
通常利用系统通信命令(原语):
Send(Receiver, message);
Receive(Sender, message);
2)间接通信方式
基于共享数据结构的实体用来暂存发送给目标进程的消息;接收进程则从该实体中,取出对方发送给自己的消息。通常把这种实体称为信箱。
4.线程的属性
多线程OS中,一个进程包括多个线程,每个线程都是利用CPU的基本单位。
(1)TCB管理的信息:
状态参数
标识符、运行状态、优先级、寄存器状态、堆栈、专有存储器、信号屏蔽等。
运行状态
执行、就绪、阻塞
(2)同步和通信机制
互斥锁、条件变量、条件变量
5.线程的实现方式
内核线程KST(kernel-level thread)
用户线程ULT(user-level thread)
组合方式

猜你喜欢

转载自blog.csdn.net/sun_sxq/article/details/83242940