信号量实现生产者消费者问题.docx
- 文档编号:4873841
- 上传时间:2023-05-07
- 格式:DOCX
- 页数:13
- 大小:519.36KB
信号量实现生产者消费者问题.docx
《信号量实现生产者消费者问题.docx》由会员分享,可在线阅读,更多相关《信号量实现生产者消费者问题.docx(13页珍藏版)》请在冰点文库上搜索。
生产者——消费者问题
一、实验目的
通过实验,掌握Windows和Linux环境下互斥锁和信号量的实现方法,加深对临界区问题和进程同步机制的理解,同时巩固利用WindowsAPI和PthreadAPI进行多线程编程的方法。
二、实验内容
1.在Windows操作系统上,利用Win32API提供的信号量机制,编写应用程序实现生产者——消费者问题。
2.在Linux操作系统上,利用PthreadAPI提供的信号量机制,编写应用程序实现生产者——消费者问题。
3.两种环境下,生产者和消费者均作为独立线程,并通过empty、full、mutex三个信号量实现对缓冲进行插入与删除。
4.通过打印缓冲区中的内容至屏幕,来验证应用程序的正确性。
三、实验步骤
㈠设计思路
①声明三个信号量,互斥信号量mutex,计数信号量empty初始化值100,技术信号量full初始化值0,并声明一个缓冲区char类型的buffer数组,大小为10,初始值为N。
②produce利用信号量形成对buffer临界生产,添加一个元素进去,赋值为A。
consume利用信号量形成对buffer临界消费,从buffer中拿出来一个元素,并将buffer中原来元素赋为B。
每访问一次临界区,就输出buffer值。
③创建多线程,其中5个生产者,和5个消费者,每个线程最多操作缓冲区10次。
㈡流程图
开始
申明3个信号量,mutex,empty,full
创建线程分别做生产者和消费者
访问临界区,并输出缓冲区的值
结束
四、主要数据结构及其说明
声明一个char类型的数组buffer,大小为10,用来做生产者和消费者共同访问的共享变量,可视做临界区。
五、程序运行时的初值和运行结果
Win32下
Linux下
六、实验体会
本实验总体感觉不是很难,就是将用信号量解决生产者消费者问题用具体的代码实现。
主要的工作就是分别在Win32和Pthread下用不同的函数名来实现P操作和V操作。
还有就是如何验证程序的正确性,就是通过没执行一次操作就输出缓冲区buffer值来判断是否符合要求。
七、源程序并附上注释
Win32下
#include
#include
#include
HANDLEEmpty,full,mutex;//声明3个信号量,互斥信号量mutex,计数信号量full和Empty
intx=0;
inty=0;
char*buffer;//缓冲区buffer
//输出buffer
voidoutput()
{
for(inti=0;i<10;i++)
{
cout< } cout<<"\n"; } DWORDWINAPIproduce(LPVOIDparam) { intj=0; do { WaitForSingleObject(Empty,INFINITE);//buffer空余量减一 WaitForSingleObject(mutex,INFINITE);//形成互斥,只能一个线程去生产 cout< //输出当前线程的id号,和执行的次数 buffer[(y++%10)]='A';//生产赋值为A output();//输出buffer j++; ReleaseSemaphore(mutex,1,NULL);//取消互斥,允许其他线程生产 ReleaseSemaphore(full,1,NULL);//可以消费量加1 }while(j! =10);//每个线程生产10次 return0; } DWORDWINAPIconsume(LPVOIDparam) { intj=0; do { WaitForSingleObject(full,INFINITE);//将可以消费量减1 WaitForSingleObject(mutex,INFINITE);//形成互斥访问,自能一个线程可以访问。 cout< buffer[x++%10]='B';//消费时,赋值为B output();//输出buffer j++; ReleaseSemaphore(mutex,1,NULL);//取消互斥,允许其他线程消费 ReleaseSemaphore(Empty,1,NULL);//buffer空余量加1 }while(j! =10);//每个线程可以消费10次 return0; } intmain() { inti; Empty=CreateSemaphore(NULL,10,10,NULL);//声明计数信号量,Empty初值为10 full=CreateSemaphore(NULL,0,10,NULL);//声明技术信号量,full初值为0 mutex=CreateSemaphore(NULL,1,1,NULL);//申明互斥信号量,初值为1 //初始化buffer数组,大小为0 buffer=newchar[10]; for(i=0;i<10;i++) { buffer[i]='N'; } //HANDLEthread; DWORD*ThreadId=(DWORD*)malloc(10*sizeof(DWORD*)); HANDLE*ThreadHandle=(HANDLE)malloc(10*sizeof(HANDLE));//创建线程句柄,分配空间 //创建5个生产者线程和5个消费者线程 for(i=0;i<5;i++) { ThreadHandle[i+5]=CreateThread(NULL,0,produce,NULL,0,&ThreadId[i+5]); ThreadHandle[i]=CreateThread(NULL,0,consume,NULL,0,&ThreadId[i]); } //让所有线程在主线程main()执行完钱全部执行完毕。 WaitForMultipleObjects(10,ThreadHandle,TRUE,INFINITE); return0; } Linux下 #include #include #include #defineBUFFER_SIZE10//缓冲区大小为10 char*buffer; sem_tmutex,empty,full;//三个信号量,互斥信号量mutex,技术信号量empty和full intx,y;//生产者和消费者在buffer中下标 voidoutput()//输出buffer数组 { inti; for(i=0;i { printf("%c",buffer[i]); printf(""); } printf("\n"); } void*produce()//生产者函数 { intj; j=0; do { sem_wait(&empty);//buffer有空余部分,可以生产,并减一 sem_wait(&mutex);//形成互斥访问,只能一个线程生产 printf("%lu%s%d%s",pthread_self(),"^^^^^",j,"^^^^^");//输出当前线程的id号,以及正在执行的次数 buffer[(x++)%BUFFER_SIZE]='A';//生产就赋值A output();//输出buffer j++; sem_post(&mutex);//取消互斥 sem_post(&full);//生成完毕,增加一个可以消费量。 }while(j! =30);//每个线程可以做30次 } void*consume()//消费者函数 { intj; j=0; do { sem_wait(&full);//可以消费的量减一 sem_wait(&mutex);//互斥访问,只能一个线程消费 printf("%lu%s%d%s",pthread_self(),"*****",j,"*****"); buffer[(y++)%BUFFER_SIZE]='B';//消费时,赋值为B output();//输出buffer值 j++; sem_post(&mutex);//取消互斥,其他线程可以消费 sem_post(&empty);//空余量加一 }while(j! =30);//每个线程可以消费30次 } intmain() { inti; x=0; y=0; buffer=(char*)malloc(BUFFER_SIZE*sizeof(char*)); for(i=0;i { buffer[i]='N'; } //semaphore sem_init(&mutex,1,1);//初始化互斥信号量mutex为1 sem_init(&empty,0,BUFFER_SIZE);//初始化计数信号量empty为BUFFER_SIZE sem_init(&full,0,0);//初始化计数信号量full为0 //multipthread pthread_ttid[10]; pthread_attr_tattr; pthread_attr_init(&attr); //创建5个生产者线程和5个消费者线程 for(i=0;i<5;i++) { pthread_create(&tid[i],&attr,consume,NULL); pthread_create(&tid[i+5],&attr,produce,NULL); } //让每个线程在主线程main执行前全部执行完毕。 for(i=0;i<10;i++) { pthread_join(tid[i],NULL); } return0; } Linux下
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 信号量 实现 生产者 消费者 问题
![提示](https://static.bingdoc.com/images/bang_tan.gif)