进程通信与进程同步机制实现.docx

上传人:b****5 文档编号:29172448 上传时间:2023-07-21 格式:DOCX 页数:27 大小:92.20KB
下载 相关 举报
进程通信与进程同步机制实现.docx_第1页
第1页 / 共27页
进程通信与进程同步机制实现.docx_第2页
第2页 / 共27页
进程通信与进程同步机制实现.docx_第3页
第3页 / 共27页
进程通信与进程同步机制实现.docx_第4页
第4页 / 共27页
进程通信与进程同步机制实现.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

进程通信与进程同步机制实现.docx

《进程通信与进程同步机制实现.docx》由会员分享,可在线阅读,更多相关《进程通信与进程同步机制实现.docx(27页珍藏版)》请在冰豆网上搜索。

进程通信与进程同步机制实现.docx

进程通信与进程同步机制实现

一.课程设计题目

某银行提供10个服务窗口(7个对私服务窗口,3个对公服务窗口)和100个供顾客等待的座位。

顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号。

取号机每次仅允许一位顾客使用,有对公和对私两类号,美味顾客只能选取其中一个。

当营业员空闲时,通过叫号选取一位顾客,并为其服务。

请用P、V操作写出进程的同步算法。

二.课程设计目的

1、掌握基本的同步与互斥算法,理解银行排队系统操作模型。

2、学习使用Windows2000/XP中基本的同步对象,掌握相关API的使用方法。

3、了解Windows2000/XP中多线程的并发执行机制,实现进程的同步与互斥。

三.课程设计要求

◆学习并理解生产者/消费者模型及其同步/互斥规则;

◆学习了解Windows同步对象及其特性;

◆熟悉实验环境,掌握相关API的使用方法;

◆设计程序,实现生产者/消费者进程(线程)的同步与互斥;

◆提交实验报告。

四.需要了解的知识

1.同步对象

同步对象是指Windows中用于实现同步与互斥的实体,包括信号量(Semaphore)、互斥量(Mutex)、临界区(CriticalSection)和事件(Events)等。

本实验中使用到信号量、互斥量和临界区三个同步对象。

2.同步对象的使用步骤:

◆创建/初始化同步对象。

◆请求同步对象,进入临界区(互斥量上锁)。

◆释放同步对象(互斥量解锁)。

五.需要用到的API函数及相关函数

我们利用WindowsSDK提供的API编程实现实验题目要求,而VC中包含有WindowsSDK的所有工具和定义。

要使用这些API,需要包含堆这些函数进行说明的SDK头文件——最常见的是Windows.h(特殊的API调用还需要包含其他头文件)。

本实验使用到的API的功能和使用方法简单介绍

1、WaitForSingleObject(hSemaphoreChairs,INFINITE);

WaitForSingleObject(hMutex,INFINITE);

●功能——使程序处于等待状态,直到信号量hHandle出现(即其值大于等于1)或超过规定的等待时间

●格式

DWORDWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds);

●参数说明

hHandle——信号量指针。

dwMilliseconds——等待的最长时间(INFINITE为无限等待)。

2、ReleaseMutex(hMutex);

●功能——打开互斥锁,即把互斥量加1。

成功调用则返回0

●格式

BOOLReleaseMutex(HANDLEhMutex);

ReleaseSemaphore(hSemaphoreShoppers,1,NULL);

●功能——对指定信号量加上一个指定大小的量。

成功执行则返回非0值

●格式

BOOLReleaseSemaphore(HANDLEhSemaphore,

LONGlReleaseCount,

LPLONGlppreviousCount);

●参数说明

hSemaphore——信号量指针。

lReleaseCount——信号量的增量。

lppreviousCount——保存信号量当前值。

3、hShoppersThread=CreateThread(NULL,0,fnTreadFunction,NULL,0,NULL);

CreateThread

●功能——创建一个在调用进程的地址空间中执行的线程

●格式

HANDLECreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,

DWORDdwStackSize,

LPTHREAD_START_ROUTINElpStartAddress,

LPVOIDlpParamiter,

DWORDdwCreationFlags,

LpdwordlpThread);

●参数说明

lpThreadAttributes——指向一个LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。

dwStackSize——定义原始堆栈大小。

lpStartAddress——指向使用LPTHRAED_START_ROUTINE类型定义的函数。

lpParamiter——定义一个给进程传递参数的指针。

dwCreationFlags——定义控制线程创建的附加标志。

lpThread——保存线程标志符(32位)

4、hMutex=CreateMutex(NULL,FALSE,NULL);

hMutexBarber=CreateMutex(NULL,FALSE,NULL);

●功能——创建一个命名或匿名的互斥量对象

●格式

HANDLECreateMutex(LPSECURITY_ATTRIBUTESlpMutexAttributes,

BOOLbInitialOwner,

LPCTSTRlpName);

5.hSemaphoreChairs=CreateSemaphore(NULL,dwWaitVolume,dwWaitVolume,NULL);

hSemaphoreShoppers=CreateSemaphore(NULL,0,dwWaitVolume,NULL);

●功能——创建一个命名或匿名的信号量对象

●格式

HANDLECreateSemaphore(LPSECURITY_ATTRIBUTESlpSemaphoreAttributes,

LONGlInitialCount,

LONGlMaximumCount,

LPCTSTRlpName);

●参数说明

lpSemaphoreAttributes——必须取值NULL。

lInitialCount——信号量的初始值。

该值大于0,但小于lMaximumCount指定的最大值。

lMaximumCount——信号量的最大值。

lpName——信号量名称。

hBarberThread=CreateThread(NULL,0,fnBarberFunction,NULL,0,NULL);

●功能——创建一个在调用进程的地址空间中执行的线程

●格式

HANDLECreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,

DWORDdwStackSize,

LPTHREAD_START_ROUTINElpStartAddress,

LPVOIDlpParamiter,

DWORDdwCreationFlags,

LpdwordlpThread);

●参数说明

lpThreadAttributes——指向一个LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。

dwStackSize——定义原始堆栈大小。

lpStartAddress——指向使用LPTHRAED_START_ROUTINE类型定义的函数。

lpParamiter——定义一个给进程传递参数的指针。

dwCreationFlags——定义控制线程创建的附加标志。

lpThread——保存线程标志符(32位)

六.原理及算法

1、信号量设置

hMutex:

取号机互斥信号量

hSemaphorePubCus:

等待对公服务顾客的数量

hSemaphorePriCus:

等待对私服务顾客的数量

hSemaphoreSeats:

剩余空座位的数量

2、线程创建

fnPubser1,fnPubser2,fnPubser3:

3个对公窗口线程

fnPriser1,fnPriser2,fnPriser3,fnPriser4,fnPriser5,fnPriser6,

fnPriser7:

7个对私窗口线程

fnPubTreadFunction:

对公顾客线程

fnPriTreadFunction:

对私顾客线程

seat:

可用座位数量

Pubcus=0:

初始对公顾客等待数量

Pricus=0:

初始对私顾客等待数量

dwCustoms=0:

初始顾客排队数量

3、P、V操作

semaphorehMutex,hSemaphorePubCus,hSemaphorePriCus,hSemaphoreSeats;

intseat,Pubcus=0,Pricus=0,dwCustoms=0;

hMutex.value=1;hSemaphorePubCus.value=0;hSemaphorePriCus.value=0;hSemaphoreSeats.value=seat;

processA//顾客线程

{inti=0;

p(&hSemaphoreSeats);

p(&hMutex);

在取号机上取号;

intset=rand()%2;

Switch(set)

{

case0:

创建对公顾客线程;

dwCustoms++;

default:

创建对私顾客线程;

dwCustoms++;

}

v(&mutex);

等待叫号;

接受服务;

v(&hSemaphorePubCus);//当取到对私服务号时为v(&hSemaphorePriCus);

}

processB//窗口线程,分对公窗口与对私窗口,执行过程相似,在此只写出其中一个窗口线程

{

P(&hSemaphorePubCus);//当取到对私服务号是为p(&hSemaphorePriCus);

若有顾客等待,则通过叫号为下一位顾客服务;

dwCustoms--;

v(&hSemaphoreSeats);

为顾客提供服务

顾客离开;

}

七.算法流程图

八.主要数据结构及实现

通过创建十二个线程来实现银行排队系统,3个对公窗口,7个对私窗口,1个对公等待顾客,1个对私等待顾客,十个窗口建立之后,来顾客就执行,没顾客就挂起,进入等待状态,通过设计一个随机数来实现对公对私窗口的区分,服务时间可以通过设计一个随机时间来实现,四个信号量,其中一个互斥信号量是取号机的,因为取号机只能一个人用,其余三个分别是等待室的信号量,对公和对私服务信号量,进来一个人时,先检查座位是否满了,没满,则取号,进入等待室,然后等待窗口叫号,当服务完时,离开并释放一个座位。

顾客线程创建过程:

(顾客线程分对公顾客线程与对私顾客线程,创建过程基本类似,下面列举对公顾客线程创建过程)

DWORDWINAPIfnPriTreadFunction(LPVOIDlpParameter)

{

/*进入等待室PV操作*/

WaitForSingleObject(hSemaphoreSeats,INFINITE);

//检查等待室有没有空位,有则继续

WaitForSingleObject(hMutex,INFINITE);

//进入等待室,同时不允许其他顾客进入

PrivateCustomers++;

cout<<"\n第"<

\n";

ReleaseMutex(hMutex);

ReleaseSemaphore(hSemaphorePrivateCustomers,1,NULL);

//释放一个信号量使顾客可以接受服务

return0;

}

窗口线程创建过程:

(窗口线程分3个对公窗口与7个对私窗口,创建过程基本类似,下面列举对公窗口1线程创建过程)

DWORDWINAPIPublicSevice2(LPVOIDlpParameter)

{

while

(1)

{

if(PublicCustomers<=2)

{

cout<<"对公窗口2空闲!

\n";

}

/*开始对公服务PV操作*/

WaitForSingleObject(hSemaphorePublicCustomers,INFINITE);

//检查有没有顾客等待服务,有则继续

WaitForSingleObject(hMutex,INFINITE);

//进入等待室时不允许其他顾客进入

WaitForSingleObject(PublicSevice2,INFINITE);

//开始服务

ReleaseMutex(hMutex);

//释放互斥量,室其他人可以进入

ReleaseSemaphore(hSemaphoreSeats,1,NULL);

//释放信号量使其它顾客可以进入等待室

cout<<"第"<

\n";

//窗口正在服务,服务延时

cout<<"第"<

\n";

WaitCustoms--;

//记录顾客离开的序号

ReleaseMutex(hSemaphoreSeats);

//释放信号量使其它顾客可以到达窗口接受服务

CloseHandle(PublicSevice2);

}

}

九.实验测试结果及结果分析

结果分析

顾客进入银行之后,首先判断是否有空座位,若有,则在取号机上取号,等待窗口服务。

对于窗口而言,只要其空闲,则按照顾客取号的顺序为顾客提供服务。

所有线程执行结束之后程序结束。

十.课程设计总结

通过此次课程设计,对银行排队系统有了较为透彻的了解,同时也了解到了c++中许多api功能函数的运用,觉得c++真的是包含了好多好多功能,以前就以为只需要学会书上的东西就行,现在发现其实不然,好多东西都是我们从实践中学习到的,好多库函数自己根本就不知道,感觉这次真的学到了好多,不仅仅是把银行排队系统理解了,更重要的是巩固了以前的知识,学到了新的东西。

回顾此次课程设计,自从拿到题目到完成整个编程,从理论到实践,我们学到很多的知识,不仅巩固了以前所学的知识,而且学到很多课外的知识,通过本次设计,让我们懂得了理论与实际相结合的重要性,只有把所学的理论知识与实践相结合,才能真正提高自己的实际动手能力和独立思考的能力。

总之,此次课程设计给我们提供了一个既动手又动脑、自学、独立实践的机会,是我们养成自学的好习惯,锻炼了实际分析问题和解决问题的能力,提高了适应实际编写的能力,为今后的学习和实践打下良好的基础。

十一.源程序清单

主要代码

#include

#include

#include

#include

#include

#include

usingnamespacestd;

DWORDseat,PublicCustomers=0,PrivateCustomers=0,WaitCustoms=0;

//分别设定座位的初始值,对公对私顾客窗口的初始值,等待顾客的初始值

HANDLEhMutex,hSemaphorePublicCustomers,hSemaphorePrivateCustomers,hSemaphoreSeats;

//分别设定取号机的互斥量,等待对公服务顾客的数量,等待对私服务顾客的数量和等待室剩余座位数的信号量

DWORDWINAPIfnPubTreadFunction(LPVOIDlpParameter)

{

/*进入等待室PV操作*/

WaitForSingleObject(hSemaphoreSeats,INFINITE);

//检查等待室有没有空位,有则继续

WaitForSingleObject(hMutex,INFINITE);

//进入等待室,同时不允许其他顾客进入

PublicCustomers++;

cout<<"\n第"<

\n";

ReleaseMutex(hMutex);

//创建对公服务窗口线程

ReleaseSemaphore(hSemaphorePublicCustomers,1,NULL);

return0;

}

DWORDWINAPIfnPriTreadFunction(LPVOIDlpParameter)

{

/*进入等待室PV操作*/

WaitForSingleObject(hSemaphoreSeats,INFINITE);

//检查等待室有没有空位,有则继续

WaitForSingleObject(hMutex,INFINITE);

//进入等待室,同时不允许其他顾客进入

PrivateCustomers++;

cout<<"\n第"<

\n";

ReleaseMutex(hMutex);

ReleaseSemaphore(hSemaphorePrivateCustomers,1,NULL);

//释放一个信号量使顾客可以接受服务

return0;

}

DWORDWINAPIPublicSevice1(LPVOIDlpParameter)

{

while

(1)

{

if(PublicCustomers<=1)

{

cout<<"对公窗口1空闲!

\n";

}

/*开始对公服务PV操作*/

WaitForSingleObject(hSemaphorePublicCustomers,INFINITE);

//检查有没有顾客等待服务,有则继续

WaitForSingleObject(hMutex,INFINITE);

//进入等待室时不允许其他顾客进入

WaitForSingleObject(PublicSevice1,INFINITE);

//开始服务

ReleaseMutex(hMutex);

//释放互斥量,室其他人可以进入

ReleaseSemaphore(hSemaphoreSeats,1,NULL);

//释放信号量使其它顾客可以进入等待室

cout<<"第"<

\n";

//窗口正在服务,服务延时

cout<<"第"<

\n";

WaitCustoms--;

//记录顾客离开的序号

ReleaseMutex(hSemaphoreSeats);

//释放信号量使其它顾客可以到达窗口接受服务

CloseHandle(PublicSevice1);

}

}

DWORDWINAPIPublicSevice2(LPVOIDlpParameter)

{

while

(1)

{

if(PublicCustomers<=2)

{

cout<<"对公窗口2空闲!

\n";

}

/*开始对公服务PV操作*/

WaitForSingleObject(hSemaphorePublicCustomers,INFINITE);

//检查有没有顾客等待服务,有则继续

WaitForSingleObject(hMutex,INFINITE);

//进入等待室时不允许其他顾客进入

WaitForSingleObject(PublicSevice2,INFINITE);

//开始服务

ReleaseMutex(hMutex);

//释放互斥量,室其他人可以进入

ReleaseSemaphore(hSemaphoreSeats,1,NULL);

//释放信号量使其它顾客可以进入等待室

cout<<"第"<

\n";

//窗口正在服务,服务延时

cout<<"第"<

\n";

WaitCustoms--;

//记录顾客离开的序号

ReleaseMutex(hSemaphoreSeats);

//释放信号量使其它顾客可以到达窗口接受服务

CloseHandle(PublicSevice2);

}

}

DWORDWINAPIPublicSevice3(LPVOIDlpParameter)

{

while

(1)

{

if(PublicCustomers<=3)

{

cout<<"对公窗口3空闲!

\n";

}

/*开始对公服务PV操作*/

WaitForSingleObject(hSemaphorePublicCustomers,INFINITE);

//检查有没有顾客等待服务,有则继续

WaitForSingleObject(hMutex,INFINITE);

//进入等待室时不允许其他顾客进入

WaitForSingleObject(PublicSevice3,INFINITE);

//开始服务

ReleaseMutex(hMutex);

//释放互斥量,室其他人可以进入

ReleaseSemaphore(hSemaphoreSeats,1,NULL);

//释放信号量使其它顾客可以进入等待室

cout<<"第"<

\n";

//窗口正在服务,服务延时

cout<<"第"<

\n";

WaitCustoms--;

//记录顾客离开的序号

ReleaseMutex(hSemaphoreSeats);

//释放信号量使其它顾客可以到达窗口接受服务

CloseHandle(PublicSevice3);

}

}

DWORDWINAPIPrivateSevice1(LPVOIDlpParameter)

{

while

(1)

{

if(PrivateCustomers<=1)

{

cout<<"对私窗口1空闲!

\n";

}

/*开始对私服务PV操作*/

WaitForSingleObject(hSemaphorePrivateCustomers,INFINITE);

//检查有没有顾客等待服务,有则继续

WaitForSingleObject(hMutex,INFINITE);

//进入等待室时不允许其他顾客进入

WaitForSingleObject(PrivateSevice1,INFINITE);

//开始服务

Rele

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 成人教育 > 电大

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1