- 生产者--消费者问题
- 分析
- 实现
- 哲学家进餐问题
- 方法一:最多4人同时拿左筷子,最终保证一人能进餐
- 方法二:同时给左右筷子
- 解法1:AND信号量
- 解法2:信号量保护机制
- 方法三:让奇数先左后右,让偶数先右后左
- 读者--写者问题
- 分析
- 实现
生产者–消费者问题 分析前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。
点击跳转到网站。
点击这里
- P1~Pl 向BUFF存信息,C1~Cm 从BUFF取信息。
- 不能对同一个信息既存又取,因此P进程和C进程互斥(mutex)
- BUFF中有空位,P进程才能存信息(empty)
- BUFF中有信息,C进程才能取信息(full)
int in = 0, out = 0; // 在BUFF中要 *** 作(存消息,取消息)的位置
item buff[n]; // 创建BUFF
semaphore mutex= 1, empty = n, full = 0;
void producer(){
do{
产生一个消息并放到nextp里
wait(empty); // 先检验是否为空
wait(mutex); // 后检验是否互斥。
顺序颠倒,在满的情况下,
// 会导致mutex无法释放,导致死锁
buff[in] = nextp;
in = (in+1)%n; // 让in指向下一个位置
signal(mutex); // 释放互斥信号
signal(full); // 放进去信息了,full+1
}while(True)
}
void consumer(){
do{
wait(full);
wait(mutex);
nextc = buff[out];
out = (out+1) mod n;
signal(mutex);
signal(empty);
消费nextc中的产品
}while(True)
}
void main(){
cobegin
producer();
consumer();
coend
}
注意:
- 每个进程中 wait(mutex)和 signal(mutex)成对存在
- 整个程序中 wait(empty/full)和 signal(empty/full)成对存在
- wait()顺序不能颠倒,先资源再互斥,避免死锁
semaphore chopsticks[5] = {1,1,1,1,1} // 5根筷子
semaphore r = 4 // 最多4个人同时拿左筷子
void ohilosopher(int i)
{
while(true){
think();
wait(r);// 看看有几个人拿了左筷子
wait(chopsticks[i]); // 拿左筷子
wait(chopsticks[(i+1)mod 5]; // 拿有筷子
eat(); // 吃
signal(chopsticks[(i+1)) mod 5]; //给出筷子
signal(chopsticks[i]);// 给出筷子
signal(r); // 1个吃完了,又允许1个人拿左筷子了
think();
}
}
方法二:同时给左右筷子
解法1:AND信号量
semaphore chopsticks[5] = {1,1,1,1,1}
void philosopher(int i){
while(true){
think();
Swait(chopsticks [i] ; chopstick[i+1] mod 5); // 用AND信号量同时给左右筷子
eat(); // 吃
Ssignal(chopstick[(i+1) mod 5];chopstick[i]) // 吃完释放一双筷子
think();
}
}
解法2:信号量保护机制
semaphore mutex = 1
semaphore chopsticks[5] = {1,1,1,1,1}
void philosopher(int i){
while(true){
think();
wait(mutex);
wait(chopstick[i]);
wait(chopstick[(i+1) mod 5]);
signal(mutex);
eat();
signal(chopstick[i]);
signal(chopstick[(i+1) mod 5]);
think();
}
}
方法三:让奇数先左后右,让偶数先右后左
semaphore chopsticks[5] = {1,1,1,1,1]
void philosopher(int i){
while(true){
if(i mod 2 == 0){
wait(chopstick[(i+1) mod 5);
wait(chopstick[i]);
eat();
signal(chopstick[i]);
signal(chopstick[(i+1) mod 5]);
}
else{
wait(chopstick[i]);
wait(chopstick[(i+1) mod 5);
eat();
signal(chopstick[(i+1) mod 5]);
signal(chopstick[i]);
}
}
}
读者–写者问题
分析
- 写者和写者之间互斥,写者和读者之间互斥
- 只要有一个读者,写者就不能去写
int Readcount = 0; // 记录有几个读者在读
semaphore rmutex = 1; // 读写互斥
semaphore wmutex = 1;// 读者之间对Readcount访问互斥
void Reader(){
do{
wait(rmutex);
if (Readcount == 0) // 判断是否是第一个读者
wait(wmutex);
Readcount++;
signal(rmutex);
read();
wait(rmutex);
Readcount--;
if (Readcount == 0){ // 判断是否是最后一个读者
signal(wmutex);
signal(wmutex);
}while(true)
}
void Writer(){
while(true){
wait(wmutex);
写;
signal(wmutex);
}
本文哲学家进餐问题参考【 *** 作系统】“哲学家进餐”问题
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)