生产者消费者模型
// 生产者消费者模型
semaphore mutex=1; // 用于多进程互斥访问缓冲区
semaphore empty=n; // 用于生产者判断,buffer是否为空位置可以放置数据
semaphore full=0; // 用于消费者判断缓冲区是否有数据可以消费
producer() {
while(1) {
// produce an item in nexp; // 生产一个数据
p(empty); // 判断buffer是否有空的位置,有空位置才可以放数据到缓冲区
p(mutex); // 对buffer加锁
// add nextp to buffer;
v(mutex); // 释放buffer
v(full); // buffer中可用数据+1
}
}
consumer() {
while(1) {
p(full); // 判断缓冲区是否有数据可以消费
p(mutex); // 对buffer加锁
// remove an item from buffer;
v(mutex); // 释放buffer
v(empty); // buffer中的空位置+1
// consume the item;
}
}
读者写者问题
/*
问题描述:有读者和写者两组并发进程,共享一个文件,当两个或以上的读进程
同时访问共享数据时不会产生副作用,但若某个写进程和其他进程
(读进程或写进程)同时访问共享数据时则可能导致数据不一致错误。
因此要求:
1、允许多个读者可以同时对文件执行读操作;
2、只允许一个写者往文件中写信息;
3、任一写者在完成写操作之前不允许其他读者或写者工作
4、写者执行写操作前,应让已有的读者和写者全部退出
*/
// 读进程优先
int count = 0; // 用来记录当前的读者数量
semaphore mutex = 1; // 用来保存更新count变量时的互斥
semaphore rw = 1; // 用来保证读者和写者互斥地访问文件
writer() { // 写者进程
while(1) {
P(rw); // 互斥访问共享文件
writing; // 写入
V(rw); // 释放共享文件
}
}
reader() { // 读者进程
while(1) {
P(mutex); // 互斥访问count变量
if(count == 0) // 当第一个读进程读共享文件时
p(rw); // 阻止写进程写
count++; // 读者计数器加1
V(mutex); // 释放互斥变量count
reading; // 读取
P(mutex); // 互斥访问count变量
count--; // 读者计数器减1
if(count==0) // 当最后一个读进程读完共享文件
V(rw); // 允许写进程写
V(mutex); // 释放互斥变量count
}
}
// 写进程优先
int count=0; // 用于记录当前的读者数量
semaphore mutex=1; // 用于保护更新count变量时的互斥
semaphore rw=1; // 用户保证读者和写者互斥地访问文件
semaphore w=1; // 用于实现写优先
writer() {
while(1) {
P(w); // 在无写进程请求时进入
P(rw); // 互斥访问共享文件
writing; // 写入
V(rw); // 释放共享文件
V(w); // 恢复对共享文件的访问
}
}
reader() {
while(1) {
P(w); // 在无写者进程请求时进入
P(mutex); // 互斥访问count变量
if(count==0) // 当第一个读进程读共享文件时
P(rw); // 阻止写进程写
count++; // 读者计数器加1
V(mutex); // 释放互斥变量count
V(w); // 恢复对共享文件的访问
reading; // 读取
P(mutex); // 互斥访问count变量
count--; // 读者计数器减1
if(count==0) // 当最后一个读进程读完共享文件
V(rw); // 允许写进程写
V(mutex); // 释放互斥变量count
}
}
哲学家就餐问题
/*
问题描述:一张圆桌上坐着5名哲学家,每两个哲学家之间的桌上有一根筷子,桌子中间有一碗米饭。
哲学家们倾注毕生精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家
饥饿的时候,才试图拿起左右两根筷子(一根一根的拿起),如果筷子已在他人手上,则
需要等待。饥饿的哲学家只有同时拿到了两根筷子才可以开始进餐,当进餐完后,放下筷
子继续思考。
*/
Pi() { // i号哲学家进程
do {
P(mutex); // 在取筷子前获得互斥量
P(chopstick[i]); // 取左边筷子
P(chopstick[i+1]); // 取右边筷子
V(mutex); // 释放取筷子的信号量
eat; // 进餐
V(chopstick[i]); // 放回左边筷子
V(chopstick[i+1]); // 放回右边筷子
think; // 思考
} while(1);
}