进程同步模拟设计——司机和售票员问题
实验三 进程同步

集美大学诚毅学院信息工程系实验报告课程名称计算机操作系统序号名称实验三进程同步姓名孙幸杰学号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)
- 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;
}
由于要表现出司机和售票员的操作过程,所以,程序是通过乘客的上下车来实现的,而具体的实现过程对于用户来说是透明的。
⑷测试用例,运行结果与运行情况分析;
本程序运行的结果如下:。