操作系统–经典进程同步与互斥问题
我以下所写的算法都是基于我所学习的书籍《计算机操作系统–第4版》的第84页 所写
仅供参考 如有错误 烦请指出
1.生产者消费者算法
semaphore mutex = 1; // 用于互斥访问
semaphore empty = n; //空闲区的数量
semaphore full = 0; //有数据的缓冲区数量(也就是产品的数量)
void 生产者()
{
while(true)
{
---生产产品---
P(empty); // 生产完产品需要申请空闲区 如果没有空闲区则需要等待
P(mutex);
---放入缓冲区---
V(mutex);
V(full); // 缓冲区新增一个产品
}
}
void 消费者()
{
while(true)
{
P(full); // 需要申请产品 如果没有产品则需要等待
P(mutex);
---拿出产品---
V(mutex);
V(empty); // 使用完产品则空出一个空闲区
---使用产品---
}
}
2.读者写者问题
① 读者优先
semaphore Rmutex = 1; // 用于实现对互斥变量Rcount的互斥访问访问
semaphore Wmutex = 1; // 用于实现对临界资源的互斥访问访问
int Rcount = 0; // 记录正在读取数据的读者的数量
void 读者()
{
while(true)
{
P(Rmutex);
if(Rcount == 0) P(Wmutex);
Rcount++;
V(Rmutex);
---读操作---
P(Rmutex);
Rcount--;
if(Rcount == 0) V(Wmutex);
V(Rmutex);
}
}
void 写者()
{
while(true)
{
P(Wmutex);
---写操作---
V(Wmutex);
}
}
②读写公平(先来先服务)
这个算法是在读者优先的基础上进行修改得来的
(增加一个互斥变量mutex 实现读写公平 实现了先来先服务)
semaphore Rmutex = 1; // 用于实现对互斥变量Rcount的互斥访问访问
semaphore Wmutex = 1; // 用于实现对临界资源的互斥访问访问
semaphore mutex = 1;
int Rcount = 0; // 记录正在读取数据的读者的数量
void 读者()
{
while(true)
{
P(mutex);
P(Rmutex);
if(Rcount == 0) P(Wmutex);
Rcount++;
V(Rmutex);
V(mutex;)
---读操作---
P(Rmutex);
Rcount--;
if(Rcount == 0) V(Wmutex);
V(Rmutex);
}
}
void 写者()
{
while(true)
{
P(mutex);
P(Wmutex);
---写操作---
V(Wmutex);
V(mutex);
}
}
③写者优先
semaphore read = 1;
semaphore mutex = 1; // 用于实现对临界资源的互斥访问访问
semaphore RC = 1; // 用于实现对互斥变量Rcount的互斥访问访问
semaphore WC = 1; // 用于实现对互斥变量Wcount的互斥访问访问
int Wcount = 0; // 记录正在写数据的写者的数量
int Rcount = 0; // 记录正在读取数据的读者的数量
void 读者()
{
while(true)
{
P(read);
P(RC);
if(Rcount == 0) P(mutex);
Rcount++;
V(RC);
V(read);
---读操作---
P(RC);
Rcount--;
if(Rcount == 0) V(mutex);
V(RC);
}
}
void 写者()
{
while(true)
{
P(WC);
if(Wcount == 0) P(read);
Wcount++;
V(WC);
P(mutex);
---写操作---
V(mutex);
P(WC);
Wcount--;
if(Wcount == 0) V(read);
V(WC);
}
}
3.哲学家进餐问题
①课本上的算法(会发生死锁)
semaphore chopstick[5] = {1,1,1,1,1};
void 哲学家()
{
while(true)
{
P(chopstick[i]); //申请左边的筷子
P(chopstick[i + 1]);//申请右边的筷子
---进餐---
V(chopstick[i]);
V(chopstick[i + 1]);
---思考---
}
}
②改进后(只允许一个人吃饭)
semaphore chopstick[5] = {1,1,1,1,1};
semaphore mutex = 1;
void 哲学家()
{
while(true)
{
P(mutex);
P(chopstick[i]); //申请左边的筷子
P(chopstick[i + 1]);//申请右边的筷子
V(mutex);
---进餐---
V(chopstick[i]);
V(chopstick[i + 1]);
---思考---
}
}
4.打瞌睡的理发师问题
#define CHAIRS = 5;
semaphore customer = 0; //等待理发师的顾客数
semaphore barners = 0; //等待顾客的理发师
semaphore mutex = 1;
int waiting = 0;
void 理发师()
{
P(customer);
P(mutex);
waiting--;
V(barners);
V(mutex);
cut_hair();
}
void 顾客()
{
P(mutex);
if(waiting < CHAIRS)
{
waiting++;
V(customers);
V(mutex);
P(barners);
get_haircut();
}
else
{
V(mutex);
}
}
5.补充:103页 售票大厅
购票者的工作过程
semaphore empty = 200;
semaphore wait = 0;
semaphore mutex = 1;
void wait()
{
P(empty);
V(wait);
}
void buy()
{
P(wait);
P(mutex);
---买票---
V(mutex);
V(empty);
}