PV操作题型整理
欢迎各路大佬指正!
基础
生产者消费者问题
void p1(){
while(1){
生产一个产品;
P(empty);
P(mutex);
把产品放入缓冲区;
V(mutex);
V(full);
}
}
void p2()
{
while(1)
{
P(full);
P(mutex);
消费一个产品;
V(mutex);
V(empty);
}
}
多生产者消费者问题(父母与两个孩子与水果的问题)
semaphore mutex=1;
semapgore plate=1;
semaphore apple=0;
semaphore orange=0;
void father(){//---爸爸生产apple
while(1)
{
准备苹果;
P(plate);
P(mutex);
把苹果放入盘子;
V(mutex);
V(apple);
}
}
void mather(){
while(1){
准备橘子;
P(plate);
P(mutex);
把橘子放入盘子;
V(mutex);
V(orange);
}
}
void daughter()
{
while(1){
P(apple);
P(mutex);
拿走苹果;
V(mutex);
V(plate);
}
}
void son(){
while(1){
P(orange);
P(mutex);
从盘子中拿走句子;
V(mutex);
V(plate);
}
}
吸烟者问题
semaphore offer1=0;
semaphore offer2=0;
semaphore offer3=0
semaphore finish=0;
int i=0;
void provider(){
while(1){
if(i==0)
{
将1放在桌子上;
V(offer1);
}
else if(i==1)
{
2放在桌子上;
V(offer2);
}
else if(i==2)
{
3放在桌子上;
V(offer3);
}
i=(i+1)%3;
P(finish);
}
}
void smoker1()
{
while(1)
{
P(offer1);
拿走1;
V(finish);
}
}
void smoker2()
{
while(1)
{
P(offer2);
拿走2;
V(finish);
}
}
void smoker3()
{
while(1)
{
P(offer3);
拿走3;
V(finish);
}
}
读-写者问题
互斥关系:写-写;读-写;
semaphore mutex=1;
semaphore rw=1;//是否存在共享文件
semaphore w=1;//写优先
int count=0;
void writer(){
while(1)
{
P(w);
P(rw);
写文件;
V(rw);
V(w);
}
}
void reader(){
while(1)
{
P(w);
P(mutex);
if(count==0)
{
P(rw);
}
count++;
V(mutex);
V(w);
读文件;
P(mutex);
count--;
if(count==0)
{
V(rw);
}
V(mutex);
}
}
哲学家进餐
(5个哲学家)
semaphore mutex=1;
semaphore chopstick[5]={1,1,1,1,1}
void Pi(){
while(1)
{
P(mutex);
P(chopstick[i]);//左
P(chopstick[(i+1)%5]);//右
V(mutex);
吃饭;
V(chopstick[i]);
V(chopstick[(i+1)%5]);
思考;
}
}
阅览室
1、有一阅览室,共有100个座位。读者进入时必须先在一种登记表上登记,该表为每一座位列一个表目,包括座号和读者姓名。读者离开时要注销掉登记内容。试用wait和signal原语描述读者进程的同步问题。
semaphore empty=100;
semaphore full=0;
semaphore mutex=1;
void add_name();
void del_name();
void Stu()
{
while(1)
{
P(empty);
P(mutex);
add_name();
坐下;
V(mutex);
阅读;
P(mutex);
del_name();
V(mutex);
V(empty);
}
}
南开到天大的小路
semaphore M=2;
semaphore k=1;
semaphore l=1;
void N_T()
{
while(1){
P(M);
P(k);
N到M;
V(k);
P(l);
V(M);
M到T;
V(l);
}
}
void T_N(){
while(1)
{
P(M);
P(l);
T到M;
V(l);
P(k);
V(M);
M到T;
V(k);
}
}
司机售票员问题
司机:启动->正常行车->到站停车;
售票员:关车门->售票->开车门;
停车后才能开车门,关车门才能行车;
semaphore car=1;
semaphore door=0;
void driver(){
while(1){
P(car);//---请求启动汽车;
启动车辆;
正常行车;
到站停车;
V(door);//释放开门变量
}
}
void ticketseller()
{
while(1)
{
关车门;
V(car);//--释放可以开车信号
售票;
P(door);//--请求开门;
开车门;
乘客上下车;
}
}
图书馆占座问题
semaphore seat=100;
semaphore mutex=1;
void P1()
{
while(1)
{
P(seat);
P(mutex);
登记;
V(mutex);
入座;
P(mutex);
注销;
V(mutex);
V(seat);
}
}
int count=100;
void P1(){
while(1)
{
P(mutex);
if(count==0)
{
回家;
V(mutex);
}
else
{
count--;
登记;
V(mutex);
入座;
P(mutex);
count++;
V(mutex);
回家;
}
}
}
独木桥
1.
semaphore mutex=1;
void P1()
{
while(1)
{
P(mutex);
过桥;
V(mutex);
}
}
2。
semaphore mutex1=1;
semaphore mutex2=1;
semaphore wait=1;
int count_1=0;
int count_2=0;
void P2()
{
while(1)
{
P(mutex1);
count_1++;
if(count_1==1)
{
P(wait);
}
V(mutex1);
过独木桥;
P(mutex1);
count_1--;
if(count_1==0)
{
V(wait);
}
V(mutex1);
}
}
void P2(){
while(1){
P(mutex2);
count_2++;
if(count_2==1)
{
P(wait);
}
V(mutex2);
过桥;
P(mutex2);
count_2--;
if(count_2==0)
{
V(wait);
}
V(mutex2);
}
}
void P1()
{
while(1)
{
P(mutex);
过桥;
V(mutex);
}
}
void P2()
{
while(1)
{
P(mutex1);
count_1++;
if(count_1==1)
{
P(wait);
}
V(mutex1);
过独木桥;
P(mutex1);
count_1--;
if(count_1==0)
{
V(wait);
}
V(mutex1);
}
}
理发师睡觉
int seat=n;
int waiting=0;//等待理发师的顾客数
semaphore barber=0;
semaphore customer=0;
semaphore mutex=1;
void barber()
{
while(1){
P(customer);//---没有顾客睡觉;
P(mutex);
waiting--;
V(barber);//---理发师去理发;
V(mutex);//释放信号量
理发;
}
}
void customer()
{
while(1){
P(mutex);
if(waiting)
{
waiting++;
V(customer);//唤醒理发师
V(mutex);
P(barber);//没有理发师时,顾客坐着
坐下等待理发;
}
else{
V(mutex);//人太多了走了
}
}
}
另一种解法:
int custNum=0;
semaphore wait=0;//等待顾客数
semaphore barber=0;
semaphore mutex=1;
void Customer(){
while(1)
{
顾客来到;
if(custNum>1){
if(customer<=N)//有顾客并且小于等于座位数
{
V(mutex);
P(wait);
}
else{
V(mutex);
离开;
}
}
else
{
V(mutex);
V(barber);
理发;
离开;
P(mutex);
custNum--;
V(mutex);
V(wait);
}
}
}
void Barber(){
while(1)
{
P(mutex);
if(custNum==0)
{
V(mutex);
P(barber);//睡觉等待;
}
else
{
V(mutex);
理发;
}
}
}
王道:
semaphore customers=0;
semaphore barber=0;
semaphore mutex=1;
int chairs=n;
int waiting=0;
void Barber(){
while(1){
P(customers); //若无顾客则睡觉;
P(mutex);
waiting--;
V(barber);//一个理发师去理发;
V(mutex);
理发;
}
}
void Customer(){
while(1){
if(waiting<chairs){
waiting++;
V(customers);//等待顾客+1
V(mutex);
P(barber);//若无理发时,则坐下休息
坐下等待理发;
}
else{
mutex;//人满,离开
}
}
}
和尚打水问题
某寺庙,有小和尚和老和尚若干,有一个水缸,由小和尚提水入缸供老和尚饮用.水缸可以容纳10桶水,水取自同一口井中,由于水井口窄,每次只能容纳一个水桶取水.水桶总数为3个。每次入水、取水仅为一桶,且不可同时进行。
semaphore well=1;//互斥访问井
semaphore vat=1;//互斥访问水缸
semaphore empty=10;//水缸剩余空间桶数
semaphore full=0;//水缸中水的桶数
semaphore pail=3;//表示还有多少桶水可以用
void old(){
while(1)
{
P(pail);
P(empty);
P(vat);
从水缸中取一桶水;
V(vat);
V(full);
喝水;
V(pail);
}
}
void young(){
while(1){
P(pail);
P(well);
P(empty);
从井中打一桶水;
V(well);
P(vat);
倒入井中;
V(vat);
V(full);
V(pail);//归还水桶
}
}
仓库问题
A,B两种货物,每次当一种,满足A-B<M; B-A<N;
semaphore Ra=M-1;
semaphore Rb=N-1;
semaphore mutex=1;
void PA(){
while(1){
P(Ra);
P(mutex);
把A放入仓库;
V(mutex);
V(Rb);
}
}
void PB()
{
while(1){
P(Rb);
P(mutex);
把B放入仓库;
V(mutex);
V(Ra);
}
}
博物馆
最多容纳500人,有一个出入口,一次一人;参观者:进门->参观->出门。
semaphore mutex=1;
semaphore empty=500;
void Visitor()
{
while(1)
{
...;
P(empty);
P(mutex);
进门;
V(mutex);
参观;
P(mutex);
出门;
V(mutex);
V(empty);
...;
}
}
面包问题
面包师有很多面包,n名销售人员。每名顾客进店后取一个号,等待叫号,当一名销售人员空闲时,叫下一号。
semaphore mutex1=1;//g顾客取号
semaphore mutex2=1;//销售叫号
int i=0;
int j=0;
void customer()
{
while(1)
{
进入面包店;
P(mutex1);
取号;
i++;
V(mutex1);
等待叫号;
}
}
void seller(){
whie(1){
P(mutex2);
if(j<i)
{
叫号j;
j++;
V(mutex2);
销售面包;
}
else{//暂时没有顾客等待
V(mutex2);
}
}
}
配件车间
有A,B两个车间生产A,B。装配车间把A,B装配成成品,两个车间每生产出一件时、后,分别配送到货架F1,F2上。F1F2都可存放10件;工人每次从货架取一件A和一件B然后组装。
semaphore empty1=10;//货架1
semaphore empty2=10//货架2
semaphore full1=0;//货架上A数量
semaphore full2=0;//货架上B数量;
semaphore mutex1=1;//互斥访问F1
semaphore mutex2=1;//互斥访问F2
void A(){
while(1){
生产一件A;
P(empty1);
P(mutex1);
把A放在货架F1;
V(mutex1);
V(full1);
}
}
void B(){
while(1){
生产一件B;
P(empty2);
P(mutex2);
把B放在F2上;
V(mutex2);
P(full2);
}
}
void Prodece(){
while(1){
P(full1);
P(mutex1);
拿走一件A;
V(mutex1);
V(empty1);
P(full2);
P(mutex2);
拿走一件B;
V(mutex2);
V(empty2);
把AB组装成品;
}
}
银行叫号
一个服务窗口,10个座位顾客等待,顾客:取号->等待->获取服务; 营业员:叫号->为客户服务;
semaphore empty=10;
semaphore mutex=1;//取号机
semaphore full=0;//已占座位数
semaphore service=0;//叫号
void costumer(){
while(1){
P(empty);
P(mutex);
从取号机上取号;
V(mutex);
V(full);
P(service);
接受服务;
}
}
void clerk(){while(1){
P(full);
V(empty);
V(service);
为顾客服务;
}}
箱子问题
生产线上有个箱子,N个位置(>=3),每个位置可存放一个车架或一个车轮,设有3名工人;工人1:加工一个车架->车界放入箱子中; 工人2:加工一个车轮->车轮入箱; 工人3:箱子中取出一个车架->取出一个车轮—>组合成一架车;
semaphore empty=10;
semaphore wheel=0;
semaphore frame=0;
semaphore s1=N-2;//车架max
semaphore s2=N-1;//车轮max
void P1(){
while(1){
加工一个车架;
P(s1);
车架入箱;
P(empty);
V(frame);
}
}
void P2(){
while(1)
{
加工一个车轮;
P(s2);
车轮入箱;
P(empty);
V(wheel);
}
}
void P3(){
while(1){
拿出一个车架;
P(frame);
V(empty);
V(s1);
拿出两个车轮;
P(wheel);
P(wheel);
V(empty);
V(empty);
V(s2);
V(s2);
组装成车;
}
}