进程同步模拟设计——司机和售票员问题
实验三 进程同步
集美大学诚毅学院信息工程系实验报告课程名称计算机操作系统序号名称实验三进程同步姓名孙幸杰学号2011957032专业计算1191 日期13.11.22成绩教师洪联系评语:1.实验目的:掌握用Linux信号灯集机制实现两个进程间的同步问题2.实验环境Win7系统虚拟机下运行的Linux系统。
3.实验内容司机与售票员问题是两个进程的同步问题,司机要启动汽车前,要检查售票员车门是否已经关好;售票员要打开车门之前要等司机把车停稳.要求:需要的信号灯: System V信号灯实现用于控制司机是否可以启动车辆的的信号灯 S1=0用于控制售票员是否可以开门的信号灯 S2=04.实验程序(有详细注释)//---------------------------------------------------//这是一个公共汽车的驾驶员与售票员之间的同步问题//一个进程模拟驾驶员,一个进程模拟售票员;//驾驶员的动作:启动车辆--驾驶车辆--到站停车//售票员的动作:关门--售票--开门;//售票员把车门关好后,驾驶员才能启动汽车;//当驾驶员在一个站把车子停稳后,售票员方能打开车门;////本程序采用System V的信号灯集实现两者的同步// 2010.10.8//-----------------------------------------------------#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <stdio.h>#include <time.h>#include <stdlib.h>union semun{int val;//仅用于SETVAL命令struct semid_ds *buf;//用于IPC_SET等命令ushort *array;//用于SETALL等命令};//用于信号灯初始化//semid--信号灯的ID//val--欲设置的信号灯初值//sn--信号灯集的分量void seminit(int semid,int val,int sn) {union semun arg;arg.val=val;semctl(semid,sn,SETVAL,arg);};//实现信号灯的P操作//semid--信号灯的ID//sn--信号灯集的分量void semdown(int semid,int sn){/* define P operating*/struct sembuf op;op.sem_num=sn;op.sem_op=-1;//P操作为-1op.sem_flg=0;semop(semid,&op,1);}//实现信号灯的V操作//semid--信号灯的ID// sn--信号灯集的分量void semup(int semid, int sn){/*define V operating*/struct sembuf op;op.sem_num=sn;op.sem_op=1;//V操作为1op.sem_flg=0;semop(semid,&op,1);}main(){int i,j;key_t semkey;char *pathname="./driver.c";int semid;int rrand;srand((int)time(0));//用于产生随机延时 semkey=ftok(pathname,45);if(semkey==-1){printf("Error:create a key error!\n");exit(-1);}semid=semget(semkey,2,IPC_CREAT | 0666);if(semid==-1){printf("Error:create semaphore error!\n");exit(-1);}seminit(semid,0,0);//对信号灯集的0号分量进行初始化seminit(semid,0,1);//对信号灯集的1号分量进行初始化if(fork()==0) //Create a process{//子进程作为驾驶员进程for(i=1;i<10;i++){semdown(semid,0);//等待售票员关门printf("Driver(pid:%d): Start the bus.\n",getpid());printf("Driver(pid:%d): Traveling....\n",getpid());rrand=1+(int)(6.0*rand()/(RAND_MAX+1.0));//产生一个(1-6)的随机数表示车辆的行驶时间sleep(rrand);printf("Driver(pid:%d): Arrive at a station. stop!\n",getpid()); semup(semid,1);//唤醒售票员}}else{//父进程作为售票员进程for(j=1;j<10;j++){printf("Conductor(pid:%d):Close all doors.\n",getpid());semup(semid,0);//唤醒司机printf("Conductor(pid:%d):Ticketing...\n",getpid());semdown(semid,1); //等待汽车到站printf("Conductor(pid:%d):Open all doors.\n",getpid());sleep(1);}}}5.实验结果及其分析输入程序:程序:编译:运行结果:6.实验小结完成本实验后,我对基本的额进程间的通信有了初步的了解。
进程同步问题例题
吃水果问题
• 问题描述:桌上有一只盘子,每次只能放入或 取出一个水果。现有许多苹果和桔子。一家四 口各行其职。爸爸专向盘中放苹果,妈妈专向 盘中放桔子,儿子专等吃盘中的桔子,女儿专 等吃盘中的苹果。请给出四人之间的同步关系, 并用PV操作实现四人正确活动的程序。
四人之间的关系
爸爸,妈妈要互斥使用盘子,所以两者 之间是互斥关系; 爸爸放的苹果,女儿吃,所以两者是同 步关系; 妈妈放的桔子,儿子吃,所以两者也是 同步关系。
• • • • •
empty,orange,apple:semaphore empty=1; orange=0; apple=0; parbegin
• Father: • • • • • •
Begin L1:P(empty); L1 P(empty); 放置苹果; V(apple); Goto L1; End;
到站停车;
图书馆阅览室问题
问题描述:假定阅览室最多可同时容纳 100个人阅读,读者进入时,必须在阅 览室门口的一个登记表上登记,内容包 括姓名、座号等,离开时要撤掉登记内 容。用P、V操作描述读者进程的同步算 法。
Sem:mutex=1,readcount=100; readeri()(i=1,2,…k) Procedure readeri()(i=1,2, k) { while(true){ P(readcount) ; p(mutex); 登记 v(mutex); 阅读 p(mutex); 撤消登记 v(mutex); v(readcount); }
Mother:
• • • • • • Begin L2: P(empty); 放置桔子; V(orange); Goto L2; End;
Son:
操作系统进程部分的习题
进程部分的习题1. 在公共汽车上,司机进程和售票员进程各司其职。
司机在正常行车中售票员售票,两者之间没有制约关系,可以任意并发。
但是在其他环节,司机和售票员进程之间存在着如下同步关系:1)司机停车后等待售票员关门后才能启动车辆。
2)售票员售完票后,等待司机到站停车,停车后才能打开车门。
var door,stop:semaphore:=0,0beginparbegin司机进程:beginwhile(true){wait(door); //等待售票员发送关门信息启动车辆;正常行车;到站停车;signal(stop);//给售票员发送到站信息}end;售票员进程:beginwhile(true){关车门;signal(door); //给司机发送关门信息售票;wait(stop);//等待司机发送到站信息开车门;上下乘客;}endparendend.2.某寺庙,有小和尚,老和尚若干。
有一水缸,由小和尚提水入缸供老和尚饮用。
水缸可容10桶水,水取自同一井中。
水井径窄,每次中能容下一个桶取水。
水桶总数为3个。
每人一次取缸水仅为1桶,且不可同时进行。
试用记录型信号量给出有关取水、入水的算法描述。
根据题意,定义信号量及其初值如下:(1)水桶为临界资源需互斥使用,定义信号量bucket,因有3个桶,故初值为3;(2)水井一次只能允许下一个桶取水,定义互斥信号量well,初值为1;(3)水缸一次只能允许一个人取水,定义互斥信号量jar,初始值为1;(4)empty和full用于小和尚和老和尚之间的同步制约关系。
因为缸能存10桶水,所以empty初始值为10;开始时缸中没有水,full的初始值为0。
semaphore bucket=3,jar=1,full=0,empty=10,well=1; young_monk(){ /*小和尚入水算法*/while(1){wait(empty);wait (bucket);wait (well);从水井中打水;signal(well);wait (jar);倒入水缸;signal (jar);signal (bucket);signal (full);}}old_monk(){ /*老和尚取水算法*/while(1){wait(full);wait (bucket);wait (jar);从缸中取水;signal (jar);signal (bucket);signal (empty);从桶中倒入饮用;}}3.设有3个进程A、B、C,其中A与B构成一对生产者与消费者(A为生产者,B为消费者),共享一个由n个缓冲区组成的缓冲池;B与C也构成一对生产者与消费者(此时B为生产者,C为消费者),共享另一个由m个缓冲区组成的缓冲池。
进程同步模拟课程设计——司机和售票员问题
附件1:学号:课程设计题目进程同步模拟设计——司机和售票员问题学院计算机科学与技术专业计算机科学与技术班级姓名指导教师2011 年 1 月21 日课程设计任务书学生姓名:专业班级:运算机科学与技术指导教师:工作单位:运算机科学与技术学院题目: 进程同步模拟设计——司机和售票员问题初始条件:1.预备内容:阅读操作系统的进程治理章节内容,对进程的同步和互斥,和信号量机制度有深切的明白得。
2.实践预备:把握一种运算机高级语言的利用。
要求完成的要紧任务:(包括课程设计工作量及其技术要求,和说明书撰写等具体要求)1.模拟公共汽车司机和售票员开关门及行车操作的同步模型。
2.设计报告内容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的要紧部份;⑷测试用例,运行结果与运行情形分析;⑸自我评判与总结:i)你以为你完成的设计哪些地址做得比较好或比较超卓;ii)什么地址做得不太好,以后如何更正;iii)从本设计取得的收成(在编写,调试,执行进程中的体会和教训);iv)完本钱题是不是有其他的其他方式(若是有,简要说明该方式);v)对实验题的评判和改良意见,请你推荐设计题目。
时刻安排:设计安排一周:周一、周2:完成程序分析及设计。
周二、周3:完成程序调试及测试。
周4、周5:验收、撰写课程设计报告。
(注意事项:严禁剽窃,一旦发觉,抄与被抄的一概按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日1.课程设计目的与功能1.1课程设计目的:通过课程设计,运用信号量,模拟公共汽车司机和售票员开关门及行车操作的同步模型。
1.2课程设计能够实现以下功能:设置信号量,保证以下四点:●公走运行的时候售票员不能开车门;●公交停下,售票员方可打开车门;●公交车门打开时,司机不能开车;●公交车门关上时,司机方能启动公交2.需求分析,数据结构或模块说明(功能与框图)2.1 需求分析●为了保证公走运行的时候车门不能开,应该设置一个表示公走运行的信号量,1表示公走运行在,0表示车已停下;●为了保证车门打开的时候司机不能启动公交,因此应设置一个表示车门是不是打开的信号量,0表示公交门打开,1表示公交门关上●依照以上分析,两个信号量在同一时刻必然相反,由此取得结论:设置一个信号量,1表示车停门开,0表示车开门关2.2 数据结构1.Bus类●成员变量:int flag表示公共的信号量,1表示车停门开,0表示车开门关●方式:public synchronized void open(),表示乘务员开车门的动作public synchronized void drive(),表示司机启动车辆的动作2.Driver类,继承于Thread类●成员变量:private Bus c,表示该司机所驾驶的公交是c●方式:public void run(),执行Bus c的driver()方式3.Conductor类,继承于Thread类●成员变量:private Bus c,表示该司机所驾驶的公交是c●方式:public void run(),执行Bus c的open()方式2.3 模块说明●Bus模块那个地址要紧介绍Bus模块中的open()与driver()方式:1.open():方式open()具有synchronized关键字,表示该方式在执行的进程中,其他方法不能够改变该方法所在对象中所拥有的值,因此保证了时间的同步性。
用多线程模拟汽车司机与售票员需求分析试验报告
操作系统:用多线程模拟汽车司机与售票员需求分析试验报告本实验利用多线程模拟汽车司机与售票员之间的协同工作即同步过程。
一方面只有售票员把车门关好了司机才能开车,因此,售票员关好车门应通知司机开车;另一方面,只有汽车已经停下,售票员才能开门上下客,故司机停车后应通知售票员。
实验的结果是在屏幕显示二者的同步过程。
一、设计过程基本原理:在Windows的一个进程内包含一个或多个线程,32位Windows环境下的WIN32 API提供了多线程应用程序开发所需的接口函数,本实验就是C++语言编写的WIN32 API的多线程编程。
具体过程:1.创建两个信号对象,设定初始值;2.创建两个子线程函数,一个为司机的操作过程,一个为售票员的操作过程。
我们在这里设定站点数为10个;在司机操作的子线程中,用一个while循环,当到最后一站时,就退出,此时,程序运行结束。
3.编写主线程函数,在其中调用两个子线程。
二、源代码#include <iostream.h>#include <windows.h>HANDLE hSemaphore1=CreateSemaphore(NULL, 0, 1, NULL);HANDLE hSemaphore2=CreateSemaphore(NULL, 0, 1, NULL);int station=1;DWORD WINAPI ThreadDriver( LPVOID LpParameter ){while(station<=10){cout<<"司机正常行车"<<endl;cout<<"前方为"<<station<<"站点"<<endl;if(station==10){cout<<"终点站到了"<<endl;return 0;}cout<<"到达"<<station<<"站点"<<endl;ReleaseSemaphore(hSemaphore2,1,NULL);WaitForSingleObject(hSemaphore1,INFINITE);cout<<"离站开车"<<station<<endl<<endl<<endl;Sleep(500);station++;}return 0;}DWORD WINAPI ThreadConductor( LPVOID LpParameter ){while(1){WaitForSingleObject(hSemaphore2,INFINITE);cout<<"售票员开门"<<endl;Sleep(1000);cout<<"乘客正在上车"<<endl;Sleep(6000);cout<<"售票员关门"<<endl;cout<<"售票员向刚上车售票"<<endl;ReleaseSemaphore(hSemaphore1,1,NULL);Sleep(1000);}return 0;}int main(){HANDLE hDriver;HANDLE hConductor;cout<<"多线程模拟司机售票员同步过程\n";cout<<"----------------------------\n";hDriver=CreateThread(NULL,0,ThreadDriver,NULL,0,NULL);Sleep(10);hConductor=CreateThread(NULL,0,ThreadConductor,NULL,0,NULL);Sleep(300000);CloseHandle(hDriver);CloseHandle(hConductor);return 0;}三、运行结果:多线程模拟司机售票员同步过程----------------------------司机正常行车前方为1站点到达1站点乘客正在上车售票员关门售票员向刚上车售票离站开车司机正常行车前方为2站点到达2站点售票员开门乘客正在上车售票员关门售票员向刚上车售票离站开车司机正常行车前方为3站点到达3站点售票员开门乘客正在上车售票员关门售票员向刚上车售票离站开车司机正常行车前方为4站点到达4站点售票员开门乘客正在上车售票员关门售票员向刚上车售票离站开车司机正常行车前方为5站点到达5站点售票员开门乘客正在上车售票员关门售票员向刚上车售票司机正常行车前方为6站点到达6站点售票员开门乘客正在上车售票员关门售票员向刚上车售票离站开车司机正常行车前方为7站点到达7站点售票员开门乘客正在上车售票员关门售票员向刚上车售票离站开车司机正常行车前方为8站点到达8站点售票员开门乘客正在上车售票员关门售票员向刚上车售票离站开车司机正常行车前方为9站点到达9站点售票员开门乘客正在上车售票员关门售票员向刚上车售票离站开车司机正常行车前方为10站点终点站到了四、程序结果分析从运行结果看,基本上模拟了司机和售票员的同步过程。
售票员和汽车司机的进程同步问题
计算机操作系统实验设计一一、实验名称:售票员和汽车司机的进程同步问题二、实验内容:创建两个进程模拟售票员和汽车司机的同步行为。
具体内容如下:1. 司机的活动:启动车辆,正常行车,到站停车。
2. 售票员活动:关车门,售票,开车门。
3. 当发车时间到,售票员关好车门后,司机才能启动车辆,售票员才开始售票。
当到站时,司机停稳车后,售票员才能打开车门,车上乘客先下车,然后站牌乘客上车。
三、设计分析:司机与售票员要协同工作:一方面只有售票员把门关好之后司机才可开车,因此售票员关好门之后要通知司机开车,然后售票;另一方面,也只有司机把车停下之后售票员才能开门让乘客下车和上车,因此,此时司机应通知售票员。
汽车当前正在始发站停车让乘客上车,因此,必须设置一定的信号量来实现他们之间的同步问题。
把司机与售票员的信号量设置为全局变量,并把客车上的人数:现在人数、下车人数、上车人数设置为全局变量;设置司机与售票员各自的线程。
考虑到第一站和最后一站的问题,应单独处理,故在各自的线程中分情况讨论:由于下车的人数是随机的,设计时考虑到了人数可能会超过客车的最大上限的问题。
具体的思路是下面的图示。
中s1是司机的信号量,s2是售票员的信号量。
实现司机与售票员之间的同步过程如下:Begins1,s2;semaphores1=0; s2=1;cobeginprocess driverbeginL1:P(s1);启动车辆;正常运行;到站停车;v(s2);goto L1;end;process conductorbeginL2:P(s2);开车门;关车门;v(s1);售票;goto L2;end;coend;end;四、算法的实现程序的实现(代码):#include<stdafx.h>#include<stdlib.h>#include<stdio.h>#include<windows.h>#include<time.h>#define Total_num 70 //客车的最大容量#define Total_pork 10 //总的站数//全局变量int Recent_num=0; //某一时刻的客车上的人数int Get_on_num; //上车的人数int Get_off_num; //下车的人数int pork=1; //客车到达路线的站数HANDLE Semaphore_driver; //Driver的信号量HANDLE Semaphore_conductor;//Conductor的信号量//产生一定范围的随机数,可避免下面程序的判断是否超出客车的最大容量问题int Get_random(int min,int max){int a;srand((int)time(0));while(1){a=rand()%(Total_num+1);if(a>=min && a<=max) return a;}}//Driver的线程DWORD WINAPI Thread_Driver(LPVOID Driver){while(pork<=Total_num){if(pork==Total_pork){WaitForSingleObject(Semaphore_driver,INFINITE); printf("终点站到了,谢谢乘坐该公交车,祝您愉快!\n");printf("到达终点站时汽车上还有%d人。
售票员与司机进程同步
cout<<NUM_DOWN<<" 名乘客下车"<<endl;
NUM_CURRENT=NUM_CURRENT-NUM_DOWN;//下车后的人数
if(NUM_CURRENT<NUM_MAX)//人数是否已满
{cout<<"没人下车"<<endl;
num_station++;
NUM_ON=random_num(NUM_MAX);
Sleep(3000);//乘客上车时间
cout<<NUM_ON<<" 名乘客上车"<<endl;
WaitForMultipleObjects(1, thread, TRUE, INFINITE); //等待两个线程结束
return 0;
}
}
}
//售票员进程
void Thread_Conductor()
{ while(true)
{ if(WaitForSingleObject(Semaphore_condutor,INFINITE)==WAIT_OBJECT_0) //判断车是否已停
if(!num_station) //第一站
NUM_CURRENT=NUM_ON+NUM_INITIAL;//起始站上车的人数
}
else
{ cout<<"车辆进站,请您注意安全!开门请当心,下车请走好!下车后请勿从车前绕行!"<<endl<<endl;
PV操作例题
S2:表示R2是否已向缓冲器存入从磁盘上读入的一个数,初始值为0.
Begin
S,S1,S2:semaphore;
S:=1;S1:=S2:=0;
Cobegin
process R1
xl:integer
begin
L1:从键盘读一个数;
x1:=读入的数;
儿子
V(SM)
P(SA)
拿苹果
V(SE)
吃苹果
女儿
V(SF)
P(SB)
拿香蕉
V(SE)
吃香蕉
问题6有一个超市,最多可容纳N个人进入购物,当N个顾客满员时,后到的顾客在超市外等待;超市中只有一个收银员。可以把顾客和收银员看作两类进程,两类进程间存在同步关系。写出用P;V操作实现的两类进程的算法(2003年系统设计员考试的题目)
答:这四个进程实际上是两个生产者R1,R2和两个消费者W1,W2.各自生成不同的产品中各自的消费对象去消费,他们共享一个的缓冲器。由于缓冲器只能存放一个数,所以,R1和R2在存放数时必须互斥。而R1和W1、R2和W2之间存在同步。为了协调它们的工作可定义三个信号量:
S:表示能否把数存人缓冲器B,初始值为1.
(3)解:从东向西的,和(2)相同;从西向东的和(1)相同。
问题4有一个俱乐部,有甲乙两个服务员,当顾客有请求时,甲负责送烟,乙负责送火,无顾客请求时,服务员睡眠。顾客自己不能带烟和火,当顾客要抽烟时,可请求服务员送烟和火,烟和火还未送到时,顾客必须等待。
设信号量:SY, SH,CY,CH:初值都为0
(1)解
设信号量MUTEX=1
P (MUTEX)
过桥
V (MUTEX)
新版进程同步典型例题
新版进程同步典型例题(总11页)本页仅作为文档封面,使用时可以删除This document is for reference only-rar21year.March进程同步练习题1. 在公共汽车上,司机和售票员的工作流程如图所示。
为保证乘客的安全,司机和售票员应密切配合协调工作。
请用信号量来实现司机与售票员之间的同步。
司机售票员图司机和售票员工作流程图2. 桌子上有一只盘子,盘子中只能放一只水果。
爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,一个儿子专等吃盘子中的橘子,一个女儿专等吃盘子中的苹果。
用PV操作实现他们之间的同步机制。
3. a,b两点之间是一段东西向的单行车道,现要设计一个自动管理系统,管理规则如下:(1)当ab之间有车辆在行驶时同方向的车可以同时驶入ab段,但另一方向的车必须在ab 段外等待;(2)当ab之间无车辆在行驶时,到达a点(或b点)的车辆可以进入ab段,但不能从a 点和b点同时驶入;(3)当某方向在ab段行驶的车辆驶出了ab段且暂无车辆进入ab段时,应让另一方向等待的车辆进入ab段行驶。
请用信号量为工具,对ab段实现正确管理以保证行驶安全。
4.将只读数据的进程称为“读者”进程,而写或修改数据的进程称为“写者”进程。
允许多个“读者”同时读数据,但不允许“写者”与其他“读者”或“写者”同时访问数据。
另外,要保证:一旦有“写者”等待时,新到达的“读者”必须等待,直到该“写者”完成数据访问为止。
试用P、V操作正确实现“读者”与“写者”的同步。
(第二类读者写者问题,信号量解决方法)5.一条河上架设了由若干个桥墩组成的一座桥。
若一个桥墩只能站一个人,过河的人只能沿着桥向前走而不能向后退。
过河时,只要对岸无人过,就可以过。
但不允许河对岸的两个人同时过,以防止出现死锁。
请给出两个方向的人顺利过河的同步算法。
6.有一个仓库,可以存放A和B两种产品,但要求:(1)每次只能存入一种产品(A或B);(2)-N<A产品数量-B产品数量<M。
进程同步模拟设计 司机和售票员问题
cout << "汽车启动准备离站......" << endl; cout << "汽车运行中......" << endl; cout << "汽车到站!" << endl; cout << "汽车停!" << endl; spy++;//相当于 v 操作。
武汉理工大学《计算机操作系统》课程设计说明书
武汉理工大学《计算机操作系统》课程设计说明书
#include<iostream> using namespace std; int spy=1, sj=0; 是司机的私有信号量。 #define SIZE 5 int n = SIZE; char ck; int p1(); int p2(); int main() { cout << "键入 a 表示乘客上车,键入 d 表示乘客下车." << endl; cout << "键入 s 表示注销进程." << endl; cout << "键入 f 表示乘客上下车过程结束." << endl << endl << endl; p1(); return 0; } int p1() { sj--;//相当于 p 操作。 if (sj == 0) { //司机的执行过程 //乘客上下车的操作变量。 //司机的操作流程。 //售票员的操作流程。 //定义车上最多能坐的人数。 //信号量的定义,spy 是售票员的私有信号量,sj
司 机 启动汽车 售票员 售票
作业1-进程同步-答案教案资料
学习资料仅供学习与参考1、 用记录型信号量解决以下问题,用类C 语言编写进程同步算法。
司机 P1 售票员 P2 REPEA T REPEA T 启动 关门 正常运行 售票 到站停 开门UNTIL FALSE UNTIL FALSE2、 两个进程合作完成数据计算和打印工作,计算进程未计算完就不可打印,反之也然,双方共用一个缓冲区,写出此算法。
3、 桌子上有一只盘子,最多可容纳两个水果,每次只能放人或取出一个水果。
爸爸专向盘子中放苹果(apple),妈妈专向盘子中放桔子(orange),两个儿子专等吃盘子中的桔子,两个女儿专等吃盘子中的苹果。
请用P 、V 操作来实现爸爸、妈妈、儿子、女儿之间的同步与互斥关系。
4、 桌子上有一只盘子,每次只能放入一只水果。
爸爸专向盘中放苹果,妈妈专向盘中放桔子,一个儿子专等吃盘中的桔子,一个女儿专等吃盘中的苹果。
请利用P 、V 操作写出父亲、母亲、儿子、女儿进程的同步算法。
5、 设有四个并发执行的进程P1、P2、P3、p4,其前趋图如下,试用信号量实现这四个进程同步。
1Var s1,s2:semaphore:=0,0; parbegin司机 P1 REPEA T wait(s1)启动正常运行 到站停 Signal(s2)UNTIL FALSE售票员 P2 REPEA T 关门Signal(s1) 售票 Wait(s2) 开门UNTIL FALSE parend 2Var empty, full: semaphore:=1,0; parbeginCalculate: beginrepeatwait(empty); 计算; signal(full); until false; end Print: beginrepeat wait(full); 打印;signal(empty); until false; end parend 3盘子为互斥资源,因可以放两个水果,empty 初值为2;再设信号量mutex 初值为1,控制对盘子的互斥访问;apple 表示盘中苹果个数,orange 表示盘中桔子个数,初值均为0。
实验1进程的同步
WaitForSingleObject(hSemaphore_condutor,INFINITE); //等待司机停车的信号
ReleaseSemaphore(hSemaphore_dirver,1,NULL);//让司机开车的信号
}
三、操作界面
cout<<"********************the end pork************************"<<endl;
return 0;
}
//司机线程
DWORD WINAPI ThreadProc_Driver(LPVOID lpParameter)
{while(NUM_PASSENGER_CURRENT<50) //车上未满座
srand(time(0));
NUM_PASSENGER_ON=rand()%10;
cout<<NUM_PASSENGER_ON<<" passengers get on the bus"<<endl;
if(!pork_begin) //如果汽车从起始站出发
{cout<<"no passengers down"<<endl;
pork_begin++;
NUM_PASSENGER_CURRENT=NUM_PASSENGER_ON+NUM_PASSENGER_INITIAL;//起始站上车的人数
}
else
{NUM_PASSENGER_CURRENT=NUM_PASSENGER_CURRENT+NUM_PASSENGER_ON;
进程同步典型例题(操作系统)
进程同步练习题1.在公共汽车上,司机和售票员的工作流程如图所示。
为保证乘客的安全,司机和售票员应密切配合协调工作。
请用信号量来实现司机与售票员之间的同步。
司机售票员图司机和售票员工作流程图①约束:怎么密切配合协调工作才能保证安全呢?a)关车门之后再启动车辆;利用前驱图解释b)到站停车之后再开车门;②根据约束定义信号量;关车门和启动车辆需要一个信号量进行同步S1;到站停车和开车门之间需要一个信号量进行同步S2;③建立几个进程呢?a)为司机建立一个进程Driver;b)为售票员建立一个进程Conductor;Driver:Repeat启动车辆;正常行驶;到站停车;Until false;Conductor:Repeat关车门;售票;开车门;Until false;④加入同步关系:Driver:RepeatWait (s1);启动车辆;正常行驶;到站停车;Signal(s2)Until false;Conductor:Repeat关车门;Signal(s1);售票;Wait(s2)开车门;Until false;main(){Driver();Conductor ();}2.桌子上有一只盘子,盘子中只能放一只水果。
爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,一个儿子专等吃盘子中的橘子,一个女儿专等吃盘子中的苹果。
用PV操作实现他们之间的同步机制。
分析:①约束:a)爸爸和妈妈竞争盘子,往盘子放水果,爸爸在放时,妈妈等待,或者相反;b)爸爸和女儿要同步,即爸爸放完苹果之后通知女儿来吃;同时女儿吃完之后要通知盘子可用;c)妈妈和儿子要同步,即妈妈放完橘子之后通知儿子来吃;同时儿子吃完之后要通知盘子可用;②经上述分析可知:需要3个信号量:S1表示临界资源盘子,初值1;爸爸和女儿需要一个信号量进行同步S2=0 妈妈和儿子需要一个信号量进行同步S3=0;③建立进程?爸爸:妈妈:女儿:儿子:取一个苹果;取一个橘子;从盘子取一个苹果;从盘子取一个橘子;放入盘子;放入盘子吃苹果;吃橘子;Until false; Until false; Until false; Until false;④加入同步关系。
公交车司机与售票员问题
【例】设公共汽车上,司机和售票员的活动分别是:
司机的活动: 售票员的活动:
在汽车不断地到站、停车、行驶过程中,这两个活动有什么同步关系?用信号量和P、V操作实现它们的同步.
解:在汽车行驶过程中,司机活动与售票员活动之间的同步关系为:售票员关车门后,向司机发开车信号,司机接到开车信号后启动车辆,在汽车正常行驶过程中售票员售票,到站时司机停车,售票员在车停后开车门让乘客上下车。
因此司机启动车辆的动作必须与售票员关车门的动作取得同步:售票员开车门的动作也必须与司机停车取得同步。
在本题中,应设置两个信号量:s1、s2,s1表示是否允许司机启动汽车,其初值为0;s2表示是否允许售票员开门,其初值为0。
用P、V原语描述如下:
我们来分析这个过程,我们把S1和S2的初值都设为0。
我们来分析分析:
1、P(S1):S1=S1-1=-1,那么司机进程就被暂停,等会售票员进程,售票员关车门.
2、V(S1):S1=S1+1=0,激活了司机进程,那么司机就开始启动车辆、正常行驶、到站停车,当然售票员也有可能同时在售票。
3、P(S2):S2=S2—1,售票员在售票之后的进程就被暂停,等待司机进程。
这样就避免了售票员售票之后就开车门了。
因为这是不允许的。
4、V(S2):S2=S2+1,司机到站停车之后,就激活了售票员P(S2)的进程,那么售票员进程就开始开车门、上下客的操作.
那么这个进程就完成了。
同步问题
解:(1)购票者之间是同步操作,因为可以同时允许 100 人进入厅内购票。 (2)根据题意,需要设置一个计数型信号量 empty,表示售票厅中还可进入
多少购票者,其初值为 100;设置一个互斥型信号量 mutex,表示购票的动作 是互斥的,初值为 1,同步过程如下:
T-buyer( ) {
While(1){ wait(empty); 进入售票厅; wait(mutex); 购票; signal(empty); signal(mutex); } }
从水缸中取水;
Signal(mutex); Signal(empty);
} }
7、 a,b 两点之间是一段东西向的单行车道,现要设计一个自动管理系统,管 理规则如下: (1) 当 ab 之间有车辆在行驶时同方向的车可以同时驶入 ab 段,但另一方 向的车必须在 ab 段外等待; (2) 当 ab 之间无车辆在行驶时,到达 a 点(或 b 点)的车辆可以进入 ab 段,但不能从 a 点和 b 点同时驶入;
countBA 为从 B 点向 A 点开的车辆数量,初值为 0;
mutexAB 为对 countAB 操作的互斥信号量,初值为 1;
mutexBA 为对 countBA 操作的互斥信号量,初值为 1;
directAB() { while(1){ Wait(mutexAB); countAB++; If (countAB ==1) wait(mutex); signal(mutexAB);
P-V操作经典例题
P就是请求资源,V就是释放资源。
问题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=1P(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=1P (MUTEX)过桥V (MUTEX)(2)解设信号量:MUTEX=1 (东西方互斥)MD=1 (东向西使用计数变量互斥)MX=1 (西向东使用计数变量互斥)设整型变量:CD=0 (东向西的已上桥人数)CX=0 (西向东的已上桥人数)从东向西:P (MD)IF (CD=0){P (MUTEX)}CD=CD+1V (MD)过桥P (MD)CD=CD-1IF (CD=0){V (MUTEX)}V (MD)从西向东:P (MX)IF (CX=0){P (MUTEX)}CX=CX+1V (MX)过桥P (MX)CX=CX-1IF (CX=0){V (MUTEX) }V (MX)(3)解:从东向西的,和(2)相同;从西向东的和(1)相同.问题4 有一个俱乐部,有甲乙两个服务员,当顾客有请求时,甲负责送烟,乙负责送火,无顾客请求时,服务员睡眠。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
题目: 进程同步模拟设计——司机和售票员问题
⑴需求分析;
本程序的功能是模拟公车的司机和售票员的开门以及行车的过程,其实也就是一个典型的进程同步互斥问题,其中主要的两点是
1:司机开车的时候,售票员不能开门,(这里体现的是进程的互斥问题)车停之后,由司机通知售票员开门(这里体现的是进程的同步问题);
2:车门开着的时候,司机不能开车,等售票员把车门关上之后,由售票员通知司机开车。
⑵功能设计(数据结构及模块说明);
本程序的设计原理比较简单,就是两大部分,一是司机的行车操作过程,另一个是售票员的开车门和关车门(以及售票,本程序不讨论售票过程)的过程。
现在来说明如何具体实现司机开车和售票员售票的相关过程。
首先,设置2个私有信号量,分别是司机和售票员的。
其中,司机的私有信号量设置为sj,其初始值为0;售票员的私有信号量为spy,其初始值为1;以上的初值表示的是司机和售票员的行车和开关车门的一个具体初始状态,具体的说也就是当车子停着,车门开着的时候的状态,此时,司机不能开车,只有当售票员售完票之后,通知司机才可以。
用操作系统书上的方法写出的流程图如下:
司机售票员
这样一来的话,仿照书上的P,V操作,实现司机和售票员之间的同步的过程如下:
begin
sj,spy;semaphore //设置司机和售票员的私有信号量;
sj=0;spy=1; //设置初始值;
cobegin
process 司机 //司机的操作过程;
begin
L1:P(sj);
启动车辆;
正常行驶;
到站停车;
V(spy);
goto L1;
end;
process 售票员 //售票员的操作过程;
begin
L2:P(spy);
开车门;
关车门;
V(sj);
售票;
goto L2;
end;
coend;
end;
⑶开发平台及源程序的主要部分;
根据以上的原理,再结合自己所学的程序开发语言,最后得出:本程序的开发平台是c++平台,其中源程序的代码如下:
#include<iostream>
using namespace std;
int spy=1, sj=0; //信号量的定义,spy是售票员的私有信号量,sj 是司机的私有信号量。
#define SIZE 5 //定义车上最多能坐的人数。
int n = SIZE;
char ck; //乘客上下车的操作变量。
int p1(); //司机的操作流程。
int p2(); //售票员的操作流程。
int main()
{
cout << "键入a表示乘客上车,键入d表示乘客下车." << endl;
cout << "键入s表示注销进程." << endl;
cout << "键入f表示乘客上下车过程结束." << endl << endl << endl;
p1();
return 0;
}
int p1() //司机的执行过程
{
sj--;//相当于p操作。
if (sj == 0)
{
cout << "汽车启动准备离站......" << endl;
cout << "汽车运行中......" << endl;
cout << "汽车到站!" << endl;
cout << "汽车停!" << endl;
spy++;//相当于v操作。
}
else sj++;
p2();
return 0;
}
int p2() //售票员的执行过程
{
spy--;//相当于p操作。
if (spy==0)
{
cout << "售票员打开车门......" << endl;
cout << "请进行乘客上下车操作!" << endl;
while (1)
{
cin >> ck;
if ((ck == 'a') && (n > 0)) {n--;cout << "上一个乘客." << endl;continue;};
if ((ck == 'd') && (n < SIZE)) {n++;cout << "下一个乘客." << endl;continue;};
if (ck == 'f') {break;};
if (ck == 's') {return 0;};
if (n <= 0) {cout << "车上座位已满,不能再上乘客了!" << endl;continue;};
if (n >= SIZE) {cout << "车上乘客已经都下完了!" << endl;continue;};
}
cout << "现在关闭车门!" << endl;
}
sj++; //相当于v操作
p1();
return 0;
}
由于要表现出司机和售票员的操作过程,所以,程序是通过乘客的上下车来实现的,而具体的实现过程对于用户来说是透明的。
⑷测试用例,运行结果与运行情况分析;
本程序运行的结果如下:。