文档库 最新最全的文档下载
当前位置:文档库 › 系统调用中的信号量PV操作 理发师问题

系统调用中的信号量PV操作 理发师问题

系统调用中的信号量PV操作 理发师问题
系统调用中的信号量PV操作 理发师问题

?理发师问题:一个理发店由一间等候室W和一间工作室B组成。顾客可以

从外面大街上进入W等候理发。两个房间的入口是并排的,且共享一扇日本式可滑动的推拉门(门总是挡住一个入口)。顾客在工作室内理完发,可由B 的旁门出去。W中有N把椅子,顾客必须坐着等候。理发师可由门上小窗查看W中无人就睡觉,否则开门,并叫一位顾客入内理发。顾客每进入一位,都拉铃通知理发师。若把顾客和理发师都视为进程,请用P、V操作写出进程的同步算法。

?要求打印:

题目中要求描述理发师和顾客的行为,因此需要两类线程barber()和customer ()分别描述理发师和顾客的行为。其中,理发师有活动有理发和睡觉两个事件;等待和理发二个事件。店里有固定的椅子数,上面坐着等待的顾客,顾客在到来这个事件时,需判断有没有空闲的椅子,理发师决定要理发或睡觉时,也要判断椅子上有没有顾客。所以,顾客和理发师之间的关系表现为:

(1)理发师和顾客之间同步关系:当理发师睡觉时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师睡觉。

(2)理发师和顾客之间互斥关系:由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n把,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。

(3)故引入3个信号量和一个控制变量:

ⅰ控制变量waiting用来记录等候理发的顾客数,初值为0;

ⅱ信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;

ⅲ信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初

值为1;ⅳ信号量mutex用于互斥,初值为1

using System;

using System.Collections.Generic;

using System.Text;

using System.Threading;

namespace理发师问题2

{

internal class Program

{

// Fields

private static Semaphore barbers = new Semaphore(1, 10);

private static int chairs;

private static int count = 0;

private static Semaphore customers = new Semaphore(0, 10);

private static int finish = 0;

private static Semaphore mtx = new Semaphore(1, 10);

private static int waiting = 0;

// Methods

public static void barber()

{

while (true)

{

customers.WaitOne();

mtx.WaitOne();

waiting--;

barbers.Release();

mtx.Release();

cuthair();

finish++;

}

}

public static void customer()

{

mtx.WaitOne();

count++;

Console.WriteLine("叮咚!第{0}个顾客来了", count);

if (waiting < chairs)

{

if (waiting > 0)

{

Console.WriteLine("此时有{0}个人在等待理发", waiting);

}

else

{

Console.WriteLine("没有人在等待");

}

waiting++;

Console.WriteLine("还有{0}个座位,顾客留下", (chairs - waiting) + 1);

mtx.Release();

customers.Release();

barbers.WaitOne();

gethaircut();

}

else

{

Console.WriteLine("座位已满,第{0}个顾客离开", count); mtx.Release();

}

}

public static void cuthair()

{

Console.WriteLine("开始理发!这是理发师的第{0}个顾客.", finish + 1);

Thread.Sleep(0x2328);

Console.WriteLine("理发完成 !");

}

public static void gethaircut()

{

Thread.Sleep(0x238c);

Console.WriteLine("第{0}个顾客理发完毕,离开.", finish);

}

private static void Main(string[] args)

{

string str = string.Empty;

Console.WriteLine("请输入椅子的总数目:");

chairs = Convert.ToInt32(Console.ReadLine());

Console.WriteLine("理发店共有{0}把椅子", chairs);

Console.WriteLine("开门接待顾客吗?Y/N");

for(string str2 = Console.ReadLine(); (str2 != "Y") && (str2 != "y"); str2 = Console.ReadLine())

{

Console.WriteLine("********对不起,尚未开门!********");

Console.WriteLine("开门接待顾客吗?Y/N");

}

Console.WriteLine("********营业中,欢迎光临!********");

new Thread(new ThreadStart(Program.barber)).Start();

while ((str != "y") && (str != "Y"))

{

Random random = new Random(https://www.wendangku.net/doc/a418640899.html,lisecond);

Thread.Sleep(random.Next(1, 0x2710));

Console.WriteLine("*******************************");

new Thread(new ThreadStart(Program.customer)).Start();

if ((finish >= 10) && (waiting == 0))

{

Console.WriteLine("已经为{0}个顾客理发了,要关门下班吗?(Y/N)", finish);

str = Console.ReadLine();

}

if ((str == "Y") || (str == "y"))

{

Console.WriteLine("************暂停营业!

**********");

break;

}

}

}

}

}

题目: 用多线程同步方法解决睡眠理发师问题(Sleeping-Barber Problem)

理发店有一位理发师,一把理发椅和n把用来等候理发的椅子。如果没有顾客,则更好师便在理发椅上睡觉,顾客到来时,如理发师闲则理发,否则如有空等候椅则坐等,没有空椅则离开,编写程序实现理发师和顾客程序,实现进程控制,要求不能出现竞争。

2.将1题中问题修改为有两位理发师,设计程序实现同步控制。

问题提示:可以用一个变量waiting来记录等候理发的顾客数,另使用三个信号量:用来记录等候理发的顾客数customers;用来记录理发师是否空闲的信息号量barbers,一个用于互斥访问waiting变量的mutex。

1已经做好了,只是想把理发师扩充问两个,求助!

初始条件:

1.操作系统:Linux

2.程序设计语言:C语言

3. 设有一个理发师,5把椅子(另外还有一把理发椅),几把椅子可用连续存储单元。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)

1.技术要求:

1)为每个理发师/顾客产生一个线程,设计正确的同步算法

2)每个顾客进入理发室后,即时显示“Entered” 及其线程自定义标识,还同时显示理发室共有几名顾客及其所坐的位置。

3)至少有10个顾客,每人理发至少3秒钟。

4)多个顾客须共享操作函数代码。

2.设计说明书内容要求:

1)设计题目与要求

2)总的设计思想及系统平台、语言、工具等。

3)数据结构与模块说明(功能与流程图)

4)给出用户名、源程序名、目标程序名和源程序及其运行结果。(要注明存储各个程序及其运行结果的主机IP地址和目录。)

5)运行结果与运行情况

(提示: (1)连续存储区可用数组实现。

(2)编译命令可用:cc -lpthread -o 目标文件名源文件名

(3)多线程编程方法参见附件。)

1设计题目与要求

1.1 设计题目

用多线程同步方法解决睡眠理发师问题(Sleeping-Barber Problem)

1.2 设计要求

1.2.1 初始条件

(1)操作系统:Linux

(2)程序设计语言:C语言

(3)设有一个理发师,5把椅子(另外还有一把理发椅),几把椅子可用连续存储单元。

1.2.2 技术要求

(1)为每个理发师/顾客产生一个线程,设计正确的同步算法

(2)每个顾客进入理发室后,即时显示“Entered” 及其线程自定义标识,还同时显示理发室共有几名顾客及其所坐的位置。

(3)至少有10个顾客,每人理发至少3秒钟。

(4)多个顾客须共享操作函数代码。

2 总体设计思想及开发环境与工具

2.1 总体设计思想

题目中要求描述理发师和顾客的行为,因此需要两类线程barber()和customer ()分别描述理发师和顾客的行为。其中,理发师有活动有理发和睡觉两个事件;等待和理发二个事件。店里有固定的椅子数,上面坐着等待的顾客,顾客在到来这个事件时,需判断有没有空闲的椅子,理发师决定要理发或睡觉时,也要判断椅子上有没有顾客。所以,顾客和理发师之间的关系表现为:

(1)理发师和顾客之间同步关系:当理发师睡觉时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师睡觉。

(2)理发师和顾客之间互斥关系:由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n把,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。

(3)故引入3个信号量和一个控制变量:

ⅰ控制变量waiting用来记录等候理发的顾客数,初值为0;

ⅱ信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;

ⅲ信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为1;ⅳ信号量mutex用于互斥,初值为1

2.2 多线程编程原理

此次在Linux下进行多线程编程需要用到pthread_create和pthread_join这两个函数。

2.2.1 创建一个线程

pthread_create用来创建一个线程,原型为:

extern int pthread_create((pthread_t *__thread, __const pthread_attr_t *__attr,void *(*__start_routine) (void *), void *__arg))

第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。函数thread不需要参数时,最后一个参数设为空指针。第二个参数设为空指针时,将生成默认属性的线程。创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。

2.2.2 等待一个线程结束

pthread_join用来等待一个线程的结束,函数原型为:

extern int pthread_join __P ((pthread_t __th, void **__thread_return));

第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存

储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被

等待的线程结束为止,当函数返回时,被等待线程的资源被收回。

2.2.3 信号量

(1)函数sem_init()用来初始化一个信号量,函数原型为:

extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));

sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,

否则只能为当前进程的所有线程共享;value给出了信号量的初始值。

(2)函数sem_post( sem_t *sem )用来增加信号量的值。

当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。

(3)函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。

2.3 伪码实现

difine n 5; //为顾客准备的椅子数为5

semaphore mutex=1; //用于互斥

semaphore customers=0;//等候理发的顾客数

semaphore barbers=1;//正在等候顾客的理发师数

int waiting=0; //等候理发的顾客数

//理发师线程

void barber()

{

while(true) //判断有无顾客

{

wait(customers); //若无顾客,理发师睡眠

wait(mutex); //互斥

waiting--; //等候顾客数少一个

signal(mutex); //释放临界资源

signal(barber); //理发师去为一个顾客理发

cut_hair; //正在理发

}

}

//顾客线程

void customer()

{

wait(mutex); //互斥

if (waiting

{

waiting++; //等候顾客数加1

signal(mutex); //释放临界资源

signal(customers); //如果理发师睡觉,唤醒理发师 wait(barber); //理发师在理发, 顾客等候

get_haircut; //顾客坐下等理发师

}

else

signal(mutex); //店里人满了,顾客离开}

}

2.4 开发环境与工具

系统平台:LINUX环境

实现语言:C语言

开发工具:NANO编辑器

3数据结构与模块说明

3.1 数据结构

通过分析课程设计要求,定义以下的数据:

sem_t mutex,customers,barbers;//design three semaphores: mutex,customer,barbers

int waiting=0; //the number of waiting customers

int chair[5];

3.2程序模块说明

3.2.1主函数模块

主函数流程图如下:

3.2.2 理发师模块

理发师模块函数流程图如下:

3.2.3 顾客模块

顾客模块函数流程图如下:

源程序代码

#include

#include

#include

#include #include #include

#include

#define n 5 //the shop have five chairs

//design three semaphores: mutex,customer,barbers

sem_t mutex,customers,barbers;

int waiting=0; //the number of waiting customers

int chair[5];

void * barber();

void * customer(void *arg);

int main(int argc,char *argv[])

{

//create 10 semaphores and one Barber semaphore

pthread_t Customer_id[10],Barber_id;

int i;

sem_init(&mutex,0,1); //init mutex semaphore to 1

sem_init(&customers,0,0);//init semaphore customers to 0

sem_init(&barbers,0,1);

for(i=0;i<5;i++)

pthread_create(&Barber_id,NULL,(void*)barber,NULL);

for (i=0;i<10;i++)

pthread_create(&Customer_id[i],NULL,(void*)customer,(void*)(i+1)); for (i=0;i<10;i++)

pthread_join(Customer_id[i],NULL);

for(i=0;i<5;i++)

pthread_join(Barber_id,NULL);

return 0;

}

//creat barber pthread

void * barber()

{

int i;

int next;

//wait(customers),if no customers,barber sleeping

sem_wait(&customers);

sem_wait(&mutex); //wait(mutex)

waiting--; //the numer of waiting reduce one

for(i=0;i<5;i++)

{

if (chair[i]!=0)

{

next= chair[i];

chair[i]=0;

break;

}

}

printf("The barber is cutting %dth customer's hair\n",next); sleep(3);

sem_post(&mutex);

sem_post(&barbers);

}

//creat customer pthread

void * customer(void *arg)

{

int i;

sem_wait(&mutex); //wait(mutex) if(waiting

if(waiting

{

waiting++; //the numer of waiting plus one

for(i=0;i<5;i++)

{

if (chair[i]==0)

{

chair[i]=(int)arg;

break;

}

}

printf("***************************************************\n"); printf("Entered:Number %d customer comes,and sits at %d chair \n",(int)arg,(i+1));

printf("There are %d customer on the chair\n",waiting);

printf("The customers' location are:");

for(i=0;i<5;i++)

printf("%d ",chair[i]);

printf("\n");

sleep(1);

sem_post(&mutex); //signal(mutex)

sem_post(&customers); //signal(customers)

sem_wait(&barbers); //wait(barbers)

}

else

{

printf("Number %d comes,there are no chairs,the customer %d is leaving\n",(int)arg,(int)arg);

sem_post(&mutex);

}

}

5.2.1 编辑,编译和运行的过程图

\

5.2.2 错误部分截图

5.2.3 正确运行结果图第一次运行结果如下图:

第二次运行结果如下图:

PV操作题解

(一)图书馆有100个座位,每位进入图书馆的读者要在登记表上登记,退出时要在登记表上注销。要几个程序有多少个进程(答:一个程序;为每个读者设一个进程) (1)当图书馆中没有座位时,后到的读者在图书馆为等待(阻塞)(2)当图书馆中没有座位时,后到的读者不等待,立即回家。 解(1 ) 设信号量:S=100; MUTEX=1 P(S) P(MUTEX) 登记 V(MUTEX) 阅读 P(MUTEX) 注销 V(MUTEX) V(S) 解(2) 设整型变量COUNT=100; 信号量:MUTEX=1; P(MUTEX); IF (COUNT==0) { V(MUTEX); RETURN; } COUNT=COUNT-1; 登记 V(MUTEX); 阅读 P(MUTEX); COUNT=COUNT+1; V(MUTEX); RETURN; (二)有一座东西方向的独木桥;用P,V操作实现:(1)每次只允许一个人过桥; (2)当独木桥上有行人时,同方向的行人可以同时过桥,相反方向的人必须等待。 (3)当独木桥上有自东向西的行人时,同方向的行人可以同时过桥,从西向东的方向,只允许一个人单独过桥。(此问题和读者与写者问题相同,东向西的为读者,西向东的为写者)。 (1)解 设信号量MUTEX=1 P (MUTEX) 过桥 V (MUTEX) (2)解 设信号量:MUTEX=1 (东西方互斥) MD=1 (东向西使用计数变量互斥) MX=1 (西向东使用计数变量互斥) 设整型变量:CD=0 (东向西的已上桥人数)

CX=0 (西向东的已上桥人数) 从东向西: P (MD) IF (CD=0) {P (MUTEX) } CD=CD+1 V (MD) 过桥 P (MD) CD=CD-1 IF (CD=0) {V (MUTEX) } V (MD) 从西向东: P (MX) IF (CX=0) {P (MUTEX) } CX=CX+1 V (MX) 过桥 P (MX) CX=CX-1 IF (CX=0) {V (MUTEX) } V (MX) (3) 解:从东向西的,和(2)相同;从西向东的和(1)相同。

pv操作的一些习题

1、进程P0和P1的共享变量定义及其初值为: boolean falg[2]; int turn=0; falg[0]=FALSE; falg[1]=FALSE; 若进程P0和P1访问临界资源的类C伪代码实现如下: 则并发执行进程P0和P1时产生的情形是【全国联考2010】 A. 不能保证进程互斥进入临界区、会出现“饥饿”现象 B. 不能保证进程互斥进入临界区、不会出现“饥饿”现象 C. 能保证进程互斥进入临界区、会出现“饥饿”现象 D. 能保证进程互斥进入临界区、不会出现“饥饿”现象 分析进程的执行过程:一开始,没有进程处于临界区中,现在进程P0开始执行,通过设置其数组元素和将turn置1来标识它希望进入临界区,由于进程P1并不想进入临界区,所以P0跳出while循环,进入临界区。如果进程P1现在开始执行,进程P1将阻塞在while循环直到flag[0]变为false,而该事件只有进程P0退出临界区时才会发生。 现在考虑两个进程几乎同时执行到while循环的情况,它们分别在turn中存入1和0,但只有后被保存进去的进程号才有效,前一个被重写而丢失。假设进程P1是后存入的,则turn为0。进程P0将循环0次而进入临界区,而进程P1则将不停地循环且不能进入临界区,直到进程退出临界区为止。 因此,该算法实现了临界区互斥。 “饥饿”出现的时机:使用忙等待实现互斥,当一个进程离开临界区时,如果有多个进程等待进入临界区,系统会随机选择一个进程执行,因为这种随机性,会导致有些进程长期得不到执行,因而导致“饥饿”。 本题中,如果P1已经等在while上的时候,P0至多执行一次临界区,否则下次执行的时候,即便它在P1测试条件前出了临界区并重新设定了flag,但由于它必须要设定turn=1(此时P1不会再设置turn了),因此这样P0必然卡在while上,从而换到P1执行。所以不会出现“饥饿”现象。 2、在一间酒吧里有三个音乐爱好者队列,第一个音乐爱好者只有随身听,第二个只有音乐磁带,第三个只有电池,而要听音乐就必须有随身听,音乐磁

PV操作的例题

PV操作的例题 一、线程是进程的一个组成部分,一个进程可以有多个线程,而且至少有一个可执行线程。进程的多个线程都在进程的地址空间内活动。 资源是分给进程的,而不是分给线程的,线程需要资源时,系统从进程的资源配额中扣除并分配给它。处理机调度的基本单位是线程,线程之间竞争处理机,真正在处理机上运行的是线程。线程在执行过程中,需要同步。 二、在计算机操作系统中,PV操作是进程管理中的难点。 首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S):①将信号量S的值减1,即S=S-1; ②如果S>=0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。 V(S):①将信号量S的值加1,即S=S+1; ②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。 PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。 什么是信号量?信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由PV操作来改变。 一般来说,信号量S>=0时,S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源,因此S的值减1;当S<0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S 的值加1;若S?0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。 利用信号量和PV操作实现进程互斥的一般模型是: 进程P1 进程P2 ……进程Pn ……………… P(S);P(S);P(S); 临界区;临界区;临界区; V(S);V(S);V(S); …………………… 其中信号量S用于互斥,初值为1。 使用PV操作实现进程互斥时应该注意的是: (1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。 (2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。(3)互斥信号量的初值一般为1。 利用信号量和PV操作实现进程同步 PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。 使用PV操作实现进程同步时应该注意的是:

pv操作练习题

用P,V操作实现下述问题的解。 一、桌上有一个盘子,可以放一个水果;父亲总是放苹果到盘子中;母亲总是放香蕉到盘子中。一个儿子专等吃盘中的香蕉,而一个女儿专等吃盘中的苹果。父母只放水果不吃,儿女只吃水果不放。实现父亲,母亲,儿子,女儿的进程同步。 二、在公共汽车上,司机和售票员的活动分别是: 司机的活动:启动车辆,正常行车,到站停车。 售票员的活动:上下乘客,关车门,售票,开车门,上下乘客。 在汽车不停的到站,停站,行驶过程中,这两个活动有什么同步关系?用信号量和P,V操作实现它们的同步。 三、某寺庙,有小,老和尚若干,有一个水缸,有小和尚提水入缸供老和尚饮用。水缸可以放10桶水,水从一个井里面提。水井狭窄,每次只能容纳一个桶取水。水桶总数为3个。每次入、取缸水只能是1桶,且不可以同时进行。试给出取水,入水的算法描述。 四、一个快餐厅有4类职员:(1)领班:接受顾客点菜,出菜单;(2)厨师:根据菜单,准备顾客的饭菜;(3)打包工:将做好的饭菜打包;(4)出纳员:收款并提交食品。每个职员可被看作一个进程,试用一种同步机制写出能让四类职员正确并发运行的程序。 五、假设有一个作业由四个进程组成,这四个进程在运行时必须按如图所示的次序依次执行,试用P,V原语表达四个进程的同步关系: 六、观察者和报告者是两个并发执行的进程,观察者不断观察并对通过的卡车计数,报告者定时的将观察者的计数值打印,打印完毕,将计数值清零。 七、假定阅览室最多可同时容纳100个人阅读,读者进入时,必须在阅览室门口的一个登记表上登记,内容包括姓名、座号等,离开时要撤掉登记内容。用P、V操作描述读者进程的同步算法。

经典PV操作讲解和练习题

在计算机操作系统中,PV操作是进程管理中的难点。 首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S):①将信号量S的值减1,即S=S-1; ②如果S30,则该进程继续执行;否则该进程置为等待状态,排入等待队列。 V(S):①将信号量S的值加1,即S=S+1; ②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。 PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。 什么是信号量?信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由PV操作来改变。 一般来说,信号量S30时,S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源,因此S的值减1;当S<0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S 的值加1;若S£0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。 利用信号量和PV操作实现进程互斥的一般模型是: 进程P1 进程P2 ……进程Pn ……………… P(S); P(S); P(S); 临界区;临界区;临界区; V(S); V(S); V(S); …………………… 其中信号量S用于互斥,初值为1。 使用PV操作实现进程互斥时应该注意的是: (1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。 (2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。(3)互斥信号量的初值一般为1。 利用信号量和PV操作实现进程同步 PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。 使用PV操作实现进程同步时应该注意的是: (1)分析进程间的制约关系,确定信号量种类。在保持进程间有正确的同步关系情况下,哪个进程先执行,哪些进程后执行,彼此间通过什么资源(信号量)进行协调,从而明确要设置哪些信号量。

信号量地PV操作(例题)

???信号量的PV操作是如何定义的?试说明信号量的PV操作的物理意义。 参考答案:P(S):将信号量S减1,若结果大于或等于0,则该进程继续执行;若结果小于0,则该进程被阻塞,并将其插入到该信号量的等待队列中,然后转去调度另一进程。 V(S):将信号量S加1,若结果大于0,则该进程继续执行;若结果小于或等于0,则从该信号量的等待队列中移出一个进程,使其从阻塞状态变为就绪状态,并插入到就绪队列中,然后返回当前进程继续执行。 PV操作的物理含义:信号量S值的大小表示某类资源的数量。当S>0时,其值表示当前可供分配的资源数目;当S<0时,其绝对值表示S信号量的等待队列中的进程数目。每执行一次P操作,S值减1,表示请求分配一个资源,若S≥0,表示可以为进程分配资源,即允许进程进入其临界区;若S<0,表示已没有资源可供分配,申请资源的进程被阻塞,并插入S的等待队列中,S的绝对值表示等待队列中进程的数目,此时CPU将重新进行调度。每执行一次V操作,S值加1,表示释放一个资源,若S>0,表示等待队列为空;若S≤0,则表示等待队列中有因申请不到相应资源而被阻塞的进程,于是唤醒其中一个进程,并将其插入就绪队列。无论以上哪种情况,执行V操作的进程都可继续运行。 1、设公共汽车上,司机和售票员的活动分别是: 司机的活动:启动车辆; 正常行车; 到站停车; 售票员的活动: 关车门; 售票; 开车门; 在汽车不断地到站、停车、行驶过程中,这两个活动有什么同步关系?用P、V操作实现它们的同步。 设两个信号量S和C,初值为S=0;C=0; 司机: L1:正常行车售票员: L2:售票 到站停车 P(S) V(S)开车门 P(C)关车门 启动开车 V(C) GO TO L1 GO TO L2 2、请用PV操作实现他们之间的同步关系: (1)桌上一个盘子,只能放一只水果。爸爸放苹果,妈妈放桔子,儿子只吃桔子,女儿只吃苹果。 (2)桌上一个盘子,只能放一只水果。爸爸放苹果,妈妈放桔子,儿子吃桔子、苹果。 参考答案: 第一步:确定进程 4个进程Father(爸爸)、Mother(妈妈)、Son(儿子)、Daughter(女儿) Father进程: 将苹果放入盘中

计算机操作系统PV操作例题

计算机操作系统P V操 作例题 WTD standardization office【WTD 5AB- WTDK 08- WTD 2C】

问题1一个司机与售票员的例子在公共汽车上,为保证乘客的安全,司机和售票员应协调工作: 停车后才能开门,关车门后才能行车。用PV操作来实现他们之间的协调。 S1:是否允许司机启动汽车的变量 S2:是否允许售票员开门的变量 driver()有三个进程R、M、P,它们共享一个缓冲区。R负责从输入设备读信息,每次读出一个记录并把它存放在缓冲区中:M在缓冲区加工读入的记录;P把加工后的记录打印输出。输入的记录经加工输出后,缓冲区中又可存放下一个记录。请用P、V操作为同步机构写出他们并发执行时能正确工作的程序。 答:三个进程共用一个缓冲区,他们必须同步工作,可定义三个信号量: S1:表示是否可把读人的记录放到缓冲区,初始值为1. S2:表示是否可对缓冲区中的记录加工,初始值为0. S3:表示记录是否加工好,可以输出,初始值也为0. 三个进程可如下设计: Begin S1,S2,S3:semaphore; S1:=l;S2:=S3:=0; cobegin process R begin L1:读记录; P(S1); 记录存入缓冲区;

V(S2); goto L1; end; process M begin L2:P(S2); 加工记录; V(S3); goto L2; end; process P begin L3:P(S3); 输出加工后的记录; V(S1); goto L3; end; coend; end. 6.现有4个进程R1,R2,W1,W2,它们共享可以存放一个数的缓冲器B.进程R1每次把从键盘上投入的一个数存放到缓冲器B中,供进程W1打印输出;进程R2每次从磁盘上读一个数放到缓冲器B中,供进程W2打印输出。当一个进程把数据存放到缓冲器后,在该数还没有被打印输出之前不准任何进程再向缓冲器中存数。在缓冲器

计算机操作系统PV操作例题

问题1 一个司机与售票员的例子 在公共汽车上,为保证乘客的安全,司机和售票员应协调工作: 停车后才能开门,关车门后才能行车。用PV操作来实现他们之间的协调。 S1:是否允许司机启动汽车的变量 S2:是否允许售票员开门的变量 driver()//司机进程 { while (1)//不停地循环 { P(S1);//请求启动汽车 启动汽车; 正常行车; 到站停车; V(S2); //释放开门变量,相当于通知售票员可以开门 } } busman()//售票员进程 { while(1) { 关车门; V(S1);//释放开车变量,相当于通知司机可以开车 售票 P(S2);//请求开门 开车门; 上下乘客; } } 注意:busman() driver() 两个不停循环的函数 问题2 图书馆有100个座位,每位进入图书馆的读者要在登记表上登记,退出时要在登记表上注销。要几个程序?有多少个进程?(答:一个程序;为每个读者设一个进程)(1)当图书馆中没有座位时,后到的读者在图书馆为等待(阻塞) (2)当图书馆中没有座位时,后到的读者不等待,立即回家。 解(1 ) 设信号量:S=100; MUTEX=1 P(S) P(MUTEX) 登记 V(MUTEX)

阅读 P(MUTEX) 注销 V(MUTEX) V(S) 解(2) 设整型变量COUNT=100; 信号量:MUTEX=1; P(MUTEX); IF (COUNT==0) { V(MUTEX); RETURN; } COUNT=COUNT-1; 登记 V(MUTEX); 阅读 P(MUTEX); COUNT=COUNT+1; V(MUTEX); RETURN; 问题3 有一座东西方向的独木桥;用P,V操作实现: (1)每次只允许一个人过桥; (2)当独木桥上有行人时,同方向的行人可以同时过桥,相反方向的人必须等待。(3)当独木桥上有自东向西的行人时,同方向的行人可以同时过桥,从西向东的方向,只允许一个人单独过桥。(此问题和读者与写者问题相同,东向西的为读者,西向东的为写者)。 (1)解 设信号量MUTEX=1 P (MUTEX) 过桥 V (MUTEX) (2)解 设信号量:MUTEX=1 (东西方互斥) MD=1 (东向西使用计数变量互斥) MX=1 (西向东使用计数变量互斥) 设整型变量:CD=0 (东向西的已上桥人数) CX=0 (西向东的已上桥人数) 从东向西: P (MD) IF (CD=0)

操作系统PV操作经典例题与答案

1. 推广例子中的消息缓冲问题。 消息缓冲区为k个,有1个发送进程,n个接收进程,每个接收进程对发送来的消息都必须取一次若有m个发送进程呢? Send: SB=k; //信号量,标记当前空余缓冲区资源。 i = 0; //标记存放消息的缓冲区位置 while (true) { P(SB); 往Buffer [i]放消息; V(SM); i = (i+1) % k; }; Receive: j = 0; //标记取产品的缓存区位置 SM=0;//信号量,标记初始没有消息 ReadCount=0;//读进程计数器 Mutex =1;//读进程互斥信号量 SW=0; //信号量,读进程在此信号量等待 while (true) { P(SM); 从Buffer[j]取消息; ReadCount++ If(ReadCount

rc=0, //正在读者计数器 wc, //写计数器 rw, //读等计数器 R //等待读信号量 W //等待写信号量 读者: while (true) { P(mutex); if (wc >0){ rw++ P (R); } rc++; If(rw>0&&wc=0){ V(R) rw-- } V(mutex); 读 P(mutex); rc --; if (rc==0){ If(wc>0)V(w) } V(mutex); }; 写者: while (true) { P(mutex); wc ++; if((wc >1)||(rc>0)){ P(W) } V(mutex); 写 P(mutex); Wc --; if(wc>0) V(W); Else if(rw>0) V(R)

操作系统PV操作习题

一、用P、V操作描述前趋关系。P1、P2、P3、P4、P5、 P6为一组合作进程,其前趋图如图2.3所示,试用P、V 操作描述这6个进程的同步。p23 图2.3说明任务启动后P1先执行,当它结束后P2、P3可以开始执行,P2完成后P4、P5可以开始执行,仅当P3、P4、P5都执行完后,P6才能开始执行。为了确保这一执行顺序,设置5个同步信号量n、摄、f3、f4、g分别表示进程P1、P2、P3、P4、P5是否执行完成,其初值均为0。这6个进程的同步描述如下:

图2.3 描述进程执行先后次序的前趋图 int f1=0; /*表示进程P1是否执行完成*/int f2=0; /*表示进程P2是否执行完成*/int f3=0; /*表示进程P3是否执行完成*/int f4=0; /*表示进程P4是否执行完成*/int f5=0; /*表示进程P5是否执行完成*/main() { cobegin P1( ); P2( ); P3( ); P4( ); P5( ); P6( ); coend } P1 ( ) { ┇ v(f1); v(f1): } P2 ( ) { p(f1); ┇ v(f2);

v(f2); ) P3 ( ) { p(f1); ┇ v(f3); } P4( ) { p(f2); ┇ v(f4); } P5 ( ) { p(f2); ┇ v(f5); } P6( ) { p(f3); p(f4); p(f5); ┇ } 二、生产者-消费者问题p25

生产者-消费者问题是最著名的进程同步问题。它描述了一组生产者向一组消费者提供产品,它们共享一个有界缓冲区,生产者向其中投放产品,消费者从中取得产品。生产者-消费者问题是许多相互合作进程的一种抽象。例如,在输入时,输入进程是生产者,计算进程是消费者;在输出时,计算进程是生产者,打印进程是消费者。因此,该问题具有很大实用价值。 我们把一个长度为n的有界缓冲区(n>0)与一群生产者进程P1、P2、…、Pm和一群消费者进程C1、C2、…、Ck 联系起来,如图2.4所示。假定这些生产者和消费者是互相等效的。只要缓冲区未满,生产者就可以把产品送入缓冲区,类似地,只要缓冲区未空,消费者便可以从缓冲区中取走物品并消耗它。生产者和消费者的同步关系将禁止生产者向满的缓冲区输送产品,也禁止消费者从空的缓冲区中提取物品。 图2.4 生产者-消费者问题 为解决这一类生产者-消费者问题,应该设置两个同步信号量,一个说明空缓冲单元的

经典PV操作问题

经典P、V操作问题详解 lionxcat@https://www.wendangku.net/doc/a418640899.html, 一、基本概念 1. 信号量 struct semaphore { int value; // 仅且必须附初值一次,初值非负 PCBtype* wait_queue; // 在此信号量上阻塞的进程队列 } S; // 信号量实例为S 2. P、V操作 P(S){ S := S-1; if (S<0) 调用进程自己阻塞自己,等待在S的等待队列末尾; } V(S){ S := S+1; if (S≤0) 从S等待队列头释放一进程就绪在就绪队列尾; 调用进程继续执行; } 3. 使用方法 (i). P、V操作成队出现,处理互斥时出现在同一进程中;处理同步时出现在不同进程中。(ii). 同步P先于互斥P调用,V的顺序无关。 4. 另类P、V操作导致的问题(或信号量的栈实现方法或漏斗法) [习题P174-23] 某系统如此定义P、V操作: P(S): S = S-1; 若S<0,本进程进入S信号量等待队列的末尾;否则,继续执行。 V(S): S=S+1; 若S≤0,释放等待队列中末尾的进程,否则继续运行。 (1)上面定义的P、V操作是否合理?有什么问题? (2)现有四个进程P1、P2、P3、P4竞争使用某一个互斥资源(每个进程可能反复使用多次),试用上面定义的P、V操作正确解决P1、P2、P3、P4对该互斥资源的使用问题。 答: (1)不合理:先进后出;可能“无限等待”,即等待队列头的进程得不到释放。 (2)思路:令每个信号量上的等待队列中始终只有一个进程。解决方案如下:(n个进程) n个进程至多有n-1个等待。设置n-1个信号量,每个进程阻塞在不同的信号量上,使每个等待队列至多有一个进程等待。用循环模拟队列。

PV操作题

PV操作题 1.独木桥问题:若规定同一方向的人可连续过桥,但同时在桥上人 数最多4人,当某方向无人过桥后,另一方向的人才能过桥.请用PV操作模拟实现. 2.独木桥问题:若规定同一方向的人可连续过桥最多10人,当某方 向连续通过达到10人后,另一方向的人才能过桥.请用PV操作模拟实现. 3.类似题目:车辆过单行隧道,火车过单行轨道 4.有一阅览室只能容纳100人(每人一个座位),读者进入时必须先在一张登记表上登记一个座位,离开时要销掉登记内容。请用PV机制描述读者进程的同步关系。 5.超市购物过程:共有100个购物篮,每人进入取一个篮子购物,出去结帐并归还篮子。出入口共用一个通道。 6.地下停车场车位管理。(共100个车位) 7.某银行最多只允许容纳N个储户办理业务,如果此时银行只有一个柜员,将此柜员和储户的行为看成两个不同进程,请用PV操作模拟上述过程。 其中储户取号等待叫号,若叫到则到柜员处办理业务,结束自行离开;柜员按顺序叫号并为储户办理业务,若N个号已取完需结束当前业务后才能让后来者取号

8. 某银行最多只允许容纳N个储户办理业务,如果此时银行有M个柜员,将此柜员和储户的行为看成两个不同进程,请用PV操作模拟上述过程。 其中储户取号等待叫号,若叫到则到柜员处办理业务,结束自行离开;柜员按顺序叫号并为储户办理业务,若N个号已取完需结束当前业务后才能让后来者取号,但是柜员间叫号是互斥的 9.有个师傅和三个徒弟,徒弟不断组装产品,做一个产品需要A,B,C 三种零件(分别被三个徒弟掌握),师傅不断提供上述三种零件,但每次只能将其中两种放到桌上,具有另一种零件的徒弟则组装产品,且做完后向师傅发信号,然后师傅再拿出两种零件放到桌上,如此反复,请用PV操作模拟上述活动。 10.书本上司机和售票员问题 后续内容继续更新中……

pv操作典型例题

例1 在某展示厅设置一个自动计数系统,以计数器count表示在场的人数,count是动态变化的,若有一个人进入展示厅进程pin对计数器count加1,当有一个人退出展示厅时,进程pout实现计数器减1。由于进、出所以展示厅的人是随机的,用P-V操作实现。(并发进程之间的互斥问题) 解:定义信号量:S——表示是否有进程进入临界区,初值为1.(表示没有进程进入临界区)begin count: Integer; S: semaphore; count:=0; S:=1; cobegin process Pin R1: Integer; begin P (S); R1:=count; R1:=R1+1; count:=R1; V(S); end; Process Pout R2: Integer;

begin P (S); R2:=count; R2:=R2-1; count:=R2; V (S); end; count; end; 例2 与生产者和消费过者相似的问题,把―A进程将记录送入缓冲器‖看生产者生产了一件物品且把物品存入缓冲器,把―B进程从缓冲器中取出记录并加工‖看作是消费者从缓冲器取出物品去消费,缓冲器中只能放一个记录(一件物品),用P-V操作实现。(并发进程之间的同步问题) 解:定义两个信号量为:sp和sg。 sp:表示生产者是否右以把物品存入缓冲器。由于缓冲器只能存放一个物品,因此sp的初值为1,即sp:=1。 sg:表示缓冲是否存有物品,它的初值应该为0,即sg:=0,表示缓冲器中还没有物品存在。 生产者和消费者两个进程并发执行时,可按以下的方式实现同步: sp:=1;sg:=0; cobegin

pv操作习题

设一民航售票系统有n个售票处。每个售票处通过终端访问系统中的公用数据区,假定公用数据区中分别用R1、R2、R3、…Rn表示×月×日×次航班的现存票数。设P1、P2、P3、Pn表示各售票处的处理进程,试用信号量实现进程间的互斥关系 Var s: semaphore :=1; begin parbegin process Pi: begin repeat Wait (s); 按旅客定票要求找到Rk if Rk>=1 then begin Rk=Rk-1; Signal (s); 输出一张票; end; else begin Signal (s); 输出“票已售完”; end; until false; end parend end 生产围棋的工人不小心把相等数量的黑子和白子混装在一个箱子里,现要用自动分拣系统把黑子和白子分开,该系统由两个并发执行的进程组成,功能如下: (1)进程A专门拣黑子,进程B专门拣白子; (2)每个进程每次只拣一个子,当一个进程在拣子时不允许另一个进程去拣子; s:semaphore:=1; parbegin process A:begin L1: Wait(s); 拣黑子; Signal(s); goto L1; end; process B:begin L2:Wait(s); 拣白子; Signal(s); goto L2; end; parend; 某车站售票厅共有20 个售票窗口,任何时刻最多可容纳20名购票者进入,当售票厅中少于20名购票者时,厅外的购票者可立即进入,否则需要在外面等待。每个购票者可看成一

个进程。 s:semaphore=20; parbegin process Pi(i=1,2,……) begin Wait(s); 进入售票厅; 购票; 退出; Signal(s); end; parend 有座东西方向架设、可双向通行的单车道简易桥,最大负荷为4 辆汽车。请定义合适的信号量,正确使用wait/signal 操作,实现双向车辆的过桥过程。 信号量应该有4 个: S ,初值为1,代表桥的互斥使用的信号量;Scounteast,初值为1,代表由东向西行驶的桥上的车辆计数器的互斥使用; Scountwest,初值为1,代表由西向东行驶的桥上的车辆计数器的互斥使用; Scount4 ,初值为4,代表桥上车辆的计数信号量。 var S,Scounteast,Scounwest,Scount4:semaphore; S: = 1;Scounteast=1; Scountwest: = 1;Scount4: = 4; Counteast,Countwest:integer; Counteast: = 0;Countwest: = 0; Cobegin , process east( i ) begin P( Scounteast ) ; if Counteast = 0 then P( S ) ; Counteast : = Counteast + l ; V( Scounteast ) ; P( Scount4 ) ; 上桥:过桥:下桥; V ( Scount4 ) ; P ( Scounteast ) ; Counteast: = Counteast - 1 ; if Counteast = 0 then V( S ) ; V ( Scounteast ) ; end ; process west( i ) begin P( Scountwest ) ; if Countwest = 0 then P( S ) ; Countwest: = Countwest + 1 ; V( Scountwest ) ;

相关文档