计算机操作系统期末复习整理---day1

235 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

经典的进程同步问题

生产者消费者问题:

1.利用信号量解决生产者消费者 例题

image.png

int in=0,out=0;
item buffer[n];
semaphore mutex=1,empty=n,full=0;

void 生产者(){
do{
   生成一个产品;
   ......
   wait(empty);
   wait(muter);
   //写进缓冲区
   buffer[in]=产品
   in=(in+1)%n;
   singal(mutex);
   singal(full)
}while(true)
}

void 消费者(){
do{
   
   wait(full);
   wait(muter);
   //写进缓冲区
   产品=buffer[out]
   out=(out+1)%n;
   singal(mutex);
   singal(empty)
   消费产品
}while(true)
}

分析:我们先按照要求定义变量。生产者消费者对于缓冲区访问是互斥的,所以我们定义mutex=1;必须要生产放进去缓冲区,消费者才能消费,所以两个是同步关系。首先,我们拿到一个空资源,然后互斥访问缓冲区,把产品放进去,然后用full+1,表示写进去一个资源。消费者,先判断有没有商品,然后再互斥访问缓冲区,最后消费了把empty+1。

2.利用add信号量解决

定义变量和之前一样的

void 生产者(){
do{
   生成一个产品;
   ......
Swait(empty,mutex)//括号里面两个资源都需要满足
   //写进缓冲区
   buffer[in]=产品
   in=(in+1)%n;
   Ssingal(mutex,full)
}while(true)
}
消费者同理修改

分析:在获取资源时候,我们必须把需要资源全部获取了才能继续下去

3.利用管程解决

分析:首先需要定义一个管程,命名pc,他包括两个过程,put(x)和get(x),分别对应生产者消费者。当count>=n表示缓冲池满了,生产者必须等待,count=0,表示缓冲池是空;消费者必须等待

对于条件变量notfull,notemploy有两个过程cwait和csingal

Monitor producerconsumerP{
item buffer[N];
condition notfull,noteempoty;
int count;
public:
void put(item x){
if(count>=N) cwait(notfull);
buffer[in]=x;
in=(in+1)%n;
count++;
csignal(notemploy)
}
void get(item x){
if(count<=0) cwait(notempty)
x=buffer[out];
out=(out+1)%N;
count--;
csignal(notfull);
}
{in=0;out=0;count=0}
}PC
void 生产者(){
item x;
while(true){
...
生产
pc.put(x)
}

void (){消费者
item x;
while(true){
...
pc.get(x)
消费
}
}

读者写者问题:

例题:来帮小朋友们解决一个问题吧:幼儿园大班和小班之间有一条刚好一人宽的过道,阿姨规定同一个方向的小朋友可以连续通过过道,当某一个方向有小朋友通过的时候,另一方向的小朋友必须乖乖排队等待;当对方没有小朋友走过道的时候,另一方向的小朋友就可以通过了。请大哥哥大姐姐们用记录型型号量帮小朋友们解决一些这个问题吧,用算法写出大班小朋友和对面小班小朋友应该遵守的代码。

semaphore wait = 1;  // 互斥信号量,表示过道的数量
int count1 = 0;       // 大班小朋友在过道上的人数
semaphore mutex1 = 1; // 大班小朋友的互斥信号量,保证count1操作的完整执行
int count2 = 0;       // 小班小朋友在过道上的人数
semaphore mutex2 = 1; // 小班小朋友的互斥信号量,保证count2操作的完整执行


P大() {
P(mutex1);
count1++;
if(count1 == 1)  // 大班第一个小朋友通过
P(wait);
V(mutex1);
{通过过道};
P(mutex1);
count1--;
if(count1 == 0)  //大班最后一个小朋友通过,释放过道
V(wait);
V(mutex1);
}

P小() {
P(mutex2);
count2++;
if(count2 == 1)  // 小班第一个小朋友通过
P(wait);
V(mutex2);
{通过过道};
P(mutex2);
count2--;
if(count2 == 0)  // 小班最后一个小朋友通过,释放过道
V(wait);
V(mutex2);
}

分析:这题属于读者写者问题,不同大小的朋友表示一类。我们先看过道是不是为空,是空可以上人,在上过道互斥pv,当下过道,也是同样pv。

哲学家就餐问题

有五个哲学家,他们的生活方式是交替地进行思考和进餐,哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,该哲学家进餐完毕后,放下左右两只筷子又继续思考。

约束条件

(1)只有拿到两只筷子时,哲学家才能吃饭。

(2)如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。

(3)任一哲学家在自己未拿到两只筷子吃完饭前,不会放下手中已经拿到的筷子。

筷子是临界资源,一段时间只允许一位哲学家使用。为了表示互斥,用一个信号量表示一只筷子,五个信号量构成信号量数组。。算法描述如下:n用五支筷子的信号量构成信号量数组:

Semaphore chopstick[5]={1,1,1,1,1};

p(stick[i]);

p(stick[(i+1) % 5]);

进餐;

v(stick[i]);

v(stick[(i+1) % 5]);

思考;

当哲学家饥饿时,总是先去拿他左边的筷子,执行wait(chopstick[I]),成功后,再去拿他右边的筷子,执行wait(chopstick[I+1]%5);成功后便可进餐。进餐毕,先放下他左边的筷子,然后再放下右边的筷子。当五个哲学家同时去取他左边的筷子,每人拿到一只筷子且不释放,即五个哲学家只得无限等待下去,引起死锁 可以采取信号量集的方法。swait,ssingal