信号量的操作.docx
- 文档编号:7051348
- 上传时间:2023-05-11
- 格式:DOCX
- 页数:8
- 大小:109.36KB
信号量的操作.docx
《信号量的操作.docx》由会员分享,可在线阅读,更多相关《信号量的操作.docx(8页珍藏版)》请在冰点文库上搜索。
信号量的操作
第一章概述----------------------------------------------1
1.实验目的-----------------------------------------------1
2.开发平台及实验环境-------------------------------------1
3.实验要求-----------------------------------------------1
第二章设计需求-----------------------------------------2
1.信号量的概念-------------------------------------------2
2.信号量的分类-------------------------------------------2
3.信号量于PV操作的关系----------------------------------2
第三章实例分析-----------------------------------------4
1.设计思想-----------------------------------------------4
2.程序代码-----------------------------------------------4
3.运行结果截图-------------------------------------------11
4.总结---------------------------------------------------11
参考文献-------------------------------------------------12
第一章概述
1.实验目的
了解信号量机制,了解并掌握进程同步和互斥机制,熟悉信号量的操作函数,利用信号量实现对共享资源的控制。
2.开发平台及实验环境:
系统平台:
windows环境
实现语言:
C++语言
开发工具:
MicrosoftVisualC++6.0
3.实验要求
通过对windows系统的内核同步对象mutexes和semaphores的使用来实现进程同步的控制。
利用CreateSemaphore、WaitForSingleObject等函数检测内核同步对象的状态。
第二章设计需求
1.信号量的概念
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。
在进入一个关键代码段之前,线程必须获取一个信号量,一旦该关键代码段完成了,那么该线程必须释放信号量。
其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。
为了完成这个过程,需要创建一个信号量VI,然后将AcquireSemaphoreVI以及ReleaseSemaphoreVI分别放置在每个关键代码段的首末端。
确认这些信号量VI引用的是初始创建的信号量。
2.信号量的分类信号量按其用途分为两种
(1).公用信号量:
初值常常为1。
用来实现进程间的互斥。
相关进程均可对其执行P、V操作。
(2).私有信号量:
初值常常为可用资源数,多用来实现进程同步。
拥有该信号量的一类进程可以对其执行P操作,而另一类进程可以对其执行V操作,,多用于并发进程的同步。
信号量按照取值可以分为两种
(1).二元信号量:
仅允许取0和1,主要用于解决进程互斥
(2).一般信号量:
计数信号量,允许取任意整数值,主要用于解决进程同步问题。
3.信号量于PV操作的关系
P操作:
信号量的值减一
如果满足if条件执行了P操作的进程会挂起P操作语句之后的语句都不会再执行。
被挂起的进程除非另一个进程调用V()来唤醒它否则永远不会执行。
V操作:
信号量的值加一
如果满足if条件,执行V操作的进程会去唤醒另一个正在等待的进程(被挂起的进程)。
执行V操作的进程不会自愿停止,V操作后面的语句会接着执行,被唤醒的进程只是进入了就绪队列,并不一定有机会马上被执行
被唤醒的进程,从挂起点接着执行,也就是P操作之后的语句
第三章实例分析
1.设计思想
假设某个饭店有一公共厕所,但是不分男女。
老板规定,当有男生上厕所时,其他男生可以进去,女生不能进入。
有女生先进去的时候其他女生可以进去,男生不能进入。
2.程序代码
#include
#include
#defineTHREADCOUNT40
HANDLEghEvent;
intiCurrentBoy=0;
intiCurrentgirl=0;
DWORDWINAPIBoyWereWCing(LPVOID);
DWORDWINAPIgirlWereWCing(LPVOID);
voidmain()
{
HANDLEaThread[THREADCOUNT];
DWORDThreadID;
inti;
//Createamutexwithnoinitialowner
ghEvent=CreateEvent(
NULL,//defaultsecurityattributes
FALSE,//beManualReset
TRUE,//initiallynotowned
NULL);//unnamedmutex
if(ghEvent==NULL)
{
printf("CreateEventerror:
%d\n",GetLastError());
return;
}
//Createworkerthreads
for(i=0;i { aThread[i]=CreateThread( NULL,//defaultsecurityattributes 0,//defaultstacksize (LPTHREAD_START_ROUTINE)BoyWereWCing, NULL,//nothreadfunctionarguments 0,//defaultcreationflags &ThreadID);//receivethreadidentifier if(aThread[i]==NULL) { printf("CreateThreaderror: %d\n", GetLastError()); return; } aThread[i+1]=CreateThread( NULL,//defaultsecurityattributes 0,//defaultstacksize (LPTHREAD_START_ROUTINE)girlWereWCing, NULL,//nothreadfunctionarguments 0,//defaultcreationflags &ThreadID);//receivethreadidentifier if(aThread[i+1]==NULL) { printf("CreateThreaderror: %d\n", GetLastError()); return; } } //Waitforallthreadstoterminate WaitForMultipleObjects(THREADCOUNT,aThread,TRUE, INFINITE); //Closethreadandmutexhandles for(i=0;i CloseHandle(aThread[i]); CloseHandle(ghEvent); } DWORDWINAPIBoyWereWCing(LPVOIDlpParam) { DWORDdwWaitResult; if(iCurrentBoy==0) { dwWaitResult=WaitForSingleObject( ghEvent,//handletomutex INFINITE);//notime-outinterval iCurrentBoy++; } else { dwWaitResult=WAIT_OBJECT_0; iCurrentBoy++; } switch(dwWaitResult) { //Thethreadgotownershipofthemutex caseWAIT_OBJECT_0: __try{ //TODO: wasbathing printf("BoyWereWCing...\n"); iCurrentBoy--; } __finally{ //Releaseownershipofthemutexobject if(iCurrentBoy==0) { if(! SetEvent(ghEvent)) { //Dealwitherror. } } } break; //Thethreadgotownershipofanabandonedmutex caseWAIT_ABANDONED: returnFALSE; } returnTRUE; } DWORDWINAPIgirlWereWCing(LPVOIDlpParam) { DWORDdwWaitResult; if(iCurrentgirl==0) { dwWaitResult=WaitForSingleObject( ghEvent,//handletomutex INFINITE);//notime-outinterval iCurrentgirl++; } else { dwWaitResult=WAIT_OBJECT_0; iCurrentgirl++; } switch(dwWaitResult) { //Thethreadgotownershipofthemutex caseWAIT_OBJECT_0: __try{ //TODO: wasbathing printf("girlWereWCing...\n"); iCurrentgirl--; } __finally{ //Releaseownershipofthemutexobject if(iCurrentgirl==0) { if(! SetEvent(ghEvent)) { //Dealwitherror. } } } break; //Thethreadgotownershipofanabandonedmutex caseWAIT_ABANDONED: returnFALSE; } returnTRUE; } 3、运行结果截图 4、总结 最开始课程设计的时候,不知道怎么做,经过一番思考后,决定选择信号量的操作这个项目。 设计这个项目不仅仅需要用到编程的知识,还需要编写相关的PV原语。 由于自己的PV原语部分学的不是很好,因此对我来说有点难。 于是我就积极利用书本上的知识来编写PV原语,不懂的地方查资料、上网找、问其他同学,最后终于把课程设计做出来了。 通过这次课程设计,感觉到自己平时动手太少,要经常动手去做实验才能真正学到东西。 尤其是编程更需要平时多加练习才能学好用好。 虽然是自己做的课程设计,但是其中还是有很多不懂的东西是问同学的,因此了解到学习不是单独的,应该是相互交流相互学习的。 参考文献: 1.操作系统原理及应用(Linux)王红 2、计算机网络操作系统原理与应用孔宪军吕滨
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 信号量 操作