用信号量进程同步与互斥
Posted ze-ze
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用信号量进程同步与互斥相关的知识,希望对你有一定的参考价值。
---恢复内容开始---
1.理解生产者和消费者问题
没有引入信号量时的生产者和消费者进程,什么情况下会出现结果不唯一?什么情况下会出现永远等待?
用信号解决生产者和消费者的同步与互斥,要求能自己写出来。
答:在两个进程同时进行时,结果会不唯一,因为不同步。
由于异常的中断,导致判断条件的重复错误,最后导致永远等待。
2.哲学家吃面问题
#include<iostream> #include<thread> #include<mutex> #include<ctime> using namespace std; using namespace std::this_thread; using namespace std::chrono; //用五个互斥量表示五支叉子 mutex fork[5]; //用一个规模为5的整型数组来表示每个盘子剩余的面条 int nuddles[5] = { 50,50,50,50,50 }; //吃面条函数 void eat(int id) { //id为哲学家编号 while (true) { //尝试同时拿起左手边和右手边的叉子 if (fork[id].try_lock()) { //先尝试拿起左手边的叉子 //如果能拿起左手边的叉子,再拿右手边的 if (fork[(id + 1) % 5].try_lock()) { //如果也能拿起右手边的叉子,吃面条 //开吃,每次吃掉的面条数量为10-20之间的一个数字 printf("哲学家%d开始吃面条!\n", id + 1); srand((unsigned)time(NULL)); int numbereated = rand() % (20 - 10 + 1) + 10; sleep_for(seconds(numbereated % 10));//吃一段时间 nuddles[id] -= numbereated; if (nuddles[id] <= 0) { printf(" 哲学家%d吃完了他的所有面条!\n", id+1); fork[id].unlock(); fork[(id + 1) % 5].unlock(); break; } printf("哲学家%d吃完,面条剩余%d!\n", id+1, nuddles[id]); fork[id].unlock(); fork[(id + 1) % 5].unlock(); sleep_for(milliseconds(200));//吃完之后歇一会,让其它哲学家能够吃上 } else { //如果没办法拿起右手边的叉子,记得要把左手边的叉子放下来 fork[id].unlock(); sleep_for(milliseconds(100));//歇一会(思考),让其它哲学家能够吃上 } } } } int main() { printf("开始吃饭!每人拥有50面条\n"); thread t1(eat, 0); thread t2(eat, 1); thread t3(eat, 2); thread t4(eat, 3); thread t5(eat, 4); t1.join(); t2.join(); t3.join(); t4.join(); t5.join(); printf("所有哲学家吃完!\n"); return 0; }
参考代码。
3.读写文件问题
nt readcount=0;
semaphore writeblock=1,mutex=1;
cobegin
process reader_i() {
P(mutex);
readcount++;
if(readcount==1)
P(writerblock);
V(mutex);
/*读文件*/
P(mutex);
readcount--;
if(readcount==0)
V(writeblock);
V(mutex); }
coend
4.理发师问题
int waiting=0, chairs=n;
semaphore customers=0,barbers=0,mutex=1;
cobegin
process barbers() {
while(ture) {
P(customers);
P(mutex);
waiting--;
V(barbers);
V(mutex);
cuthair(); } }
process customer_i() {
P(mutex);
if(waiting<chairs) {
waiting++;
V(customers);
V(mutex);
P(barbers):
get_haircut();
}
else
V(mutex);
}
coend
5.在一间酒吧里有三个音乐爱好者队列,第一队的音乐爱好者只有随身听,第二队只有音乐磁带,第三队只有电池。而要听音乐就必须随身听、音乐磁带和电池这三种物品俱全。酒吧老板一次出售这三种物品中的任意两种。当一名音乐爱好者得到这三种物品并听完一首乐曲后,酒吧老板才能再一次出售这三种物品中的任意两种。于是第二名音乐爱好者得到这三种物品,并开始听乐曲。全部买卖就这样进行下去。试用P,v操作正确解决这一买卖。
semaphore muext=1;
cobegin
process boss(){
P(muext);
/*老板任意出售两种*/
V(muext);
}
process musiclovers_i() {
while(ture){
P(muext);
listening();
V(muext);
} }
coend
6.某银行有人民币储蓄业务,由n个储蓄员负责。每个顾客进入银行后先取一个号,并且等着叫号。当一个储蓄人员空闲下来,就叫下一个号。请用P,V操作正确编写储蓄人员和顾客进程的程序。
semaphore customers=0,clerk=0,mutex=n;
int waiting=0;
cobegin
process clerk() {
while(ture){
P(customers);
P(mutex);
waiting--;
V(clerk);
V(mutex);
service();
} }
process customer_i() {
P(mutex);
waiting++;
V(customers);
V(mutex);
P(clerk):
get_service();
}
coend
7.下面是两个并发执行的进程。它们能正确运行吗?若不能请举例说明,并改正之。(5分)
parbegin
var X:integer;
process P1 process P2
var y,z:integer: var t,u:integer;
begin begin
x:=1; x:=0:
y:=0: t=0;
if x≥l then y:=y十1; if x≤l then t:=t+2;
z:=y; u:=t;
end; end;
parend.
parbegin
var x:integer; var s:semaphore:=1;
process P1 process P2
var y,z:integer ; var ,tu:integer ;
begin begin
P(s); P(s);
x:=1; x:=0;
y:=0; t:=0;
if x>=1 then y:=y+1; if x<=1 then t:=t+2
V(s); V(s);
z:=y; u:=t;
end end
parend
8.九、在一个盒子里,混装了相等数量的黑棋子和白棋子,现要用自动分拣系统把黑棋子和白棋子分开,该系统由两个并发执行的进程P1和P2组成,其中进程P1专门拣黑子,进程P2专门拣白子。规定两个进程轮流拣子且每个进程每次只拣一个子。当一个进程在拣子时不允许另一个进程去拣子,并设P1先拣。请用P,V操作管理这两个并发进程,使其能正确实现上述功能。
semaphore s1=1,s2=0;
cobegin {
process P1
begin
repeat
P(s1);
拣黑子;
V(s2);
until false;
end
process P2
begin
repeat
P(s2);
拣白子;
V(s1);
until false;
end
}
coend
以上是关于用信号量进程同步与互斥的主要内容,如果未能解决你的问题,请参考以下文章