生产流水线问题

  • 在生产流水线上有三个工序:取件(getter),传送(transfer),加工(processor)。刚开始可以取件,才能通过传送带传送,传送带送到加工的位置才能进行加工,然后才可以开始下一轮的取件。试用信号量的P、V操作实现getter、transfer、processor之间的同步与互斥关系,补全下面代码中的空白。每个空白计1分。


信号量 g____sema = (1);// 指示可取件的信号量,初始值设定
信号量 t____sema = (0);// 指示可传送访的信号量,初始值设定
信号量 p____sema = (0);// 指示可加工的信号量,初始值设定
void getter () { //取件
while( true ) {
P(g____sema);
取件工序操作
V(t____sema)
}
}
void transfer () {//传送
while( true ) {
P(t____sema);
传送工序操作
V(p____sema)
}
}
void processor () { //加工
while( true ) {
P(p____sema);
加工工序操作
V(g____sema)
}
}
void main() {
创建getter进程
创建transfer进程
创建processor进程
其他处理
}

三个进程问题

  • 三个进程P1、P2、P3互斥使用一个包含N(N>0)个单元的缓冲区。P1每次用produce()生成一个正整数并用put()送入缓冲区某一空单元中;P2每次用getodd()从该缓冲区中取出一个奇数并用countodd()统计奇数个数;P3每次用geteven()从该缓冲区中取出一个偶数并用counteven()统计偶数个数。请用信号量机制实现这三个进程的同步与互斥活动,并说明所定义信号量的含义。要求用伪代码描述。
//P1、P2、P3互斥,使用N
信号量 Nempty = N; //缓冲区空闲空间个数
信号量 Nsem = 1; //缓冲区的某一时刻只有一个进程访问。

void P1(){
while(true){
produce(); //生成正整数
P(Nempty);
P(Nsem);
put(); //送入缓冲区N
V(Nsem);
}
}
void P2(){
while(true){
P(Nsem);
getodd(); //从N中取出一个奇数
V(Nsem);
V(Nempty);
countodd(); //统计奇数个数
}
}
void P3(){
while(true){
P(Nsem);
geteven(); //从N中取出一个偶数
P(Nsem);
V(Nempty);
counteven(); //统计偶数个数
}
}

前趋图题

  • 用PV原语表达以下进程前趋图中进程间的约束关系。

设a,b,c,d,e,f,g = 0;
P1: P1;V(a),V(b),V(c);
P2: P(a);P2;V(d);
P3: P(c);P3;V(f);
P4: P(b);P4;V(e);
P5: P(f);P5;V(g);
P6: P(d),P(e),P(g);P6;

小、老和尚喝水问题

某寺庙有小和尚和老和尚若干,水缸一只,由小和尚提水入缸供老和尚饮用。水缸可容水10桶,水取自同一口水井中。水井径窄,每次仅能容纳一只水桶取水,水桶共三只。每次放入、取出的水量仅为一桶,试用PV操作写出小和尚打水、放入水缸、老和尚取水喝的过程。

  • 先分析同步,后分析互斥
信号量 empty = 10;  //表示水缸容量
信号量 full = 0; //表示水缸初值
信号量 bucket = 3; //水井取水互斥
信号量 water = 1; //水缸喝水互斥
小和尚:
{

P(bucket); //申请水桶
P(well); //水井互斥
从水井取水;
V(well);
P(empty); //申请水缸容量
P(water); //申请倒入
倒入缸中;
V(water);
V(full);
V(bucket); //放回水桶
}
老和尚:
{
P(bucket); //申请水桶
P(full);
P(water); //申请水缸取水
从水缸取水;
V(water);
V(empty);
喝水;
V(bucket); //放回水桶
}

一家四口吃水果问题

桌上有一只盘子,最多可容纳2个水果,每次只能放入或取出1个水果。爸爸专向盘中放苹果,妈妈专向盘中放橘子;一个儿子专等吃盘子中的橘子,一个女儿专等吃盘中的苹果。试用信号量的P、V操作实现爸爸、妈妈、儿子、女儿之间的同步与互斥关系,补全下面代码中的空白。每个空白计1分。

Semaphore sEmpty = __2__;
Semaphore sApple = __0__;
Semaphore sOrange =__0__;
Semaphore sMutex =__1__;
void father() {
while(true) {
P(__sEmpty__);
P(__sMutex__);
向盘中放苹果
V(sMutex)
V(sApple)
}
}
void mother() {
while(true) {
P(sEmpty);
P(sMutex);
向盘中放橘子
V(sMutex)
V(__sOrange__)
}
}
void son( ) {
while(true) {
P(sOrange);
P(sMutex);
从盘中取橘子
V(sMutex);
V(sEmpty);
吃橘子
}
}
void daughter( ) {
while(true) {
P(__sApple__);
P(sMutex);
从盘中取苹果
V(sMutex);
V(sEmpty);
吃苹果
}
}

仓库入库问题

有一个仓库,可以存放A和B两种产品,但要求:(1) 每次只能存入一个产品(A或B);(2) -N<A产品数量-B产品数量<M。其中,N和M是正整数。试用P、V操作描述产品A与产品B的入库过程。




理发店问题

某个理发店有n个椅子。当没有顾客时,理发师去睡觉。如果有顾客进来时,理发师正在睡觉,这个顾客会叫醒他,如果没有椅子,顾客直接离开。试用P、V操作描述以上过程。

参考:https://mp.weixin.qq.com/s/PX7U6cAJdRFgHjm5J83Qbg

变量 waiting = 0;
信号量 barbers = 0, customers = 0,mutex = 1;
barber()
{
P(customers);
P(mutex);
waiting := waiting–1;
V(mutex);
V(barbers);
cut-hair;
}
customer()
{
P(mutex);
if (waiting < n)
{
waiting :=waiting+1;
V(mutex);
V(customers);
P(barbers);
get-haircut;
}else
V(mutex); //因为if条件中使用了变量,因此两个分支都需要释放互斥信号量

}

哲学家就餐问题

有 n( n≥3) 位哲学家围坐在一张圆桌边, 每位哲学家交替地就餐和思考。 在圆桌中心有 m(m≥1) 个碗, 每两位哲学家之间有一根筷子。 每位哲学家必须取到一个碗和两侧的筷子后, 才能就餐, 进餐完毕, 将碗和筷子放回原位, 并继续思考。 为使尽可能多的哲学家同时就餐, 且防止出现死锁现象, 请使用信号量的 P、 V 操作描述上述过程中的互斥与同步, 并说明所用信号量及初值的含义。

信号量 wan = m;       //m>=1,碗的数量
信号量 chop[n] = {1}; //n>=3,筷子数等于哲学家数

void 哲学家(i)
{
if(i为奇数)
{
p(chop[i]);
p(chop[(i+1)%n]);
p(wan);
}else{
p(chop[(i+1)%n]);
p(chop[i]);
p(wan);
}
就餐();
v(wan);
v(chop[i]);
v(chop[(i+1)%n]);
思考();
}
//等待的时候是不是也要思考?应该不行吧,交替地就餐和思考,等待就餐就不能思考