计算机操作系统课程设计报告生产者---消费者问题_第1页
计算机操作系统课程设计报告生产者---消费者问题_第2页
计算机操作系统课程设计报告生产者---消费者问题_第3页
计算机操作系统课程设计报告生产者---消费者问题_第4页
计算机操作系统课程设计报告生产者---消费者问题_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、计算机操作系统课程设计题目:生产者一消费者问题专 业:软件工程年级:2010级小组成员:丝上指导教师:时 间:地 点:2012年5月摘要生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问 题(英语:Bounded-buffer problem ),是一个多线程同步问题的经典案例。该 问题描述了两个共享固定大小缓冲区的线程一一即所谓的“生产者”和“消费者”在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓 冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题 的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在

2、缓冲区中空时消耗数据。生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯, 而通过阻塞队列来进行通讯,所以生产者生 产完数据之后不用等待消费者处理, 直接扔给阻塞队列,消费者不找生产者要数 据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。444445557889141717错误!未定义书签。18目录.概述.课程设计任务及要求设计任务设计要求分工日程表.算法及数据结构算法的总体思想生产者模块消费者模块.程序设计与实现程序流程图程序代码实验结果. 结论.收获、体会和建议收获.参考文献.概述本课题设计是完成了 “操

3、作系统原理”课程进行的一次全面的综合训练,通 过这次课程设计,充分检验学生对课程的掌握程度和熟练情况, 让学生更好的掌 握操作系统的原理及其实现方法,加深对课程的基础理论和算法的理解, 加强学 生的动手能力。.课程设计任务及要求. 1设计任务通过研究Linux的进程机制和信号量实现生产者消费者问题的并发控制.说明:有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1-20 这20个整型数。. 2设计要求(1)每个生产者和消费者对有界缓冲区进行操作后,实时显示有界缓冲区的 全部内容、当前指针位置和生产者/消费者的标识符。(2)生产者和消费者各有两个以上。(3)多个生产者或多个消费者之间须有

4、共享对缓冲区进行操作的函数代码。提示:(1)有界缓冲区可用数组实现。3分工日程表周二卜午周四上午周四卜午周五上午周五卜午A分析题目讨论,分工编写代码测试系统编写文档B分析题目讨论,分工编写代码添加备注完善系统3,算法及数据结构1算法的总体思想在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。 消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等 待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓 冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。2生产者模

5、块功能在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。当生产者线程生产物品 时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一 个空缓冲区。数据结构producer_semaphore/生产者的资源信号量(初始值为缓冲区的大小)Bufferpn /有界缓冲区Pn / 缓冲区目标位置MAX_BUFFER/缓冲区上限buffer_mutex/互斥信号量Wait()/等待操作,用于申请资源Signal()/信号操作,用于释放资源Sleep()/ 挂起算法void *producer_thread(void *tid)pthre

6、ad_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);/* 设置状态,PTHREAD_CANCEL_ENABLE是正常处理 cancel信号*/while(1)等待,需要生存*/sem_wait(&producer_semaphore); /* srand(int)time(NULL)*(int)tid);sleep(rand()%2+1); /*一个或两个需要生产 */while(produce_pointer+1)%20=consume_pointer); /*指针位置*/sem_wait(&buffer_mutex); /* 缓存区 */buffer

7、produce_pointer=rand()%20+1;/*指针位置 */produce_pointer=(produce_pointer+1)%20; /*指针位置 */*判断*/if(produce_pointer=0)printf( 生产者:%d 指针指向:%2d 生产产品号:2dn,(int)tid,19,buffer19);/*输出生产者,指针,缓存区*/fprintf(fd, 生产者:%d指针指向:%2d生产产品号:2dn,(int)tid,19,buffer19);/*输出生产者,指针,缓存区*/elseprintf( 生产者:%d 指针指向:%2d 生产产品号:%2dn,(in

8、t)tid,produce_pointer-1,bufferproduce_pointer-1);/*输出生产者,指针,缓存区 */fprintf(fd, 生产者:%d 指针指向:%2d 生产产品号:%2dn,(int)tid,produce_pointer-1,bufferproduce_pointer-1);/*输出生产者,指针,缓存区 */showbuf();sem_post(&buffer_mutex);sem_post(&consumer_semaphore); /*通知消费者缓冲区不是空的*/srand(int)time(NULL)*(int)tid);sleep(rand()%5

9、+1); /*等待几秒钟,然后继续生产*/return (void*)0);3.3消费者模块功能消费者线程从缓冲区中获得物品,然后释放缓冲区。当消费者线程消费物品 时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。数据结构consumer_semaphore/消费者的资源信号量(初始值为0)Bufferpn /有界缓冲区Pn /缓冲区目标位置MAX_BUFFER缓冲区上限buffer_mutex/互斥信号量Wait()/等待操作,用于申请资源Signal。/信号操作,用于释放资源Sleep() 挂起算法void *consumer_thread(void *tid)/*可

10、以被其他线程使用*/pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);/* 设置状态,PTHREAD_CANCEL_ENABLE 是忽略 cancel 信号*/while(1)sem_wait(&consumer_semaphore); /*通知消费者消费 */srand(int)time(NULL)*(int)tid);sleep(rand()%2+1);/*一个或两个来消费 */sem_wait(&buffer_mutex);printf( 消费者:%d指针指向:%2d消费产品号:%2dn,(int)tid,consume_pointer

11、,bufferconsume_pointer);/*输出消费者,消费者指针,缓存区 */fprintf(fd, 消费者:%d 指针指向:%2d 消费产品号:%2dn,(int)tid,consume_pointer,bufferconsume_pointer);/*输出消费者,消费者指针,缓存区 */bufferconsume pointer=0; /*消费者指针指向 0*/consume_pointer=(consume_pointer+1)%20;showbuf();sem_post(&buffer_mutex);sem_post(&producer_semaphore);/*通知生产者缓

12、冲区不是空的*/srand(int)time(NULL)*(int)tid);sleep(rand()%5+1); /*等待几秒钟,然后继续消费*/return (void*)0);.程序设计与实现程序流程图程序代码#include#include#include#include#include#include#include#include#include #include#define NUM_THREADS_P 5#define NUM_THREADS_C 5#define MAX_BUFFER 20#define RUN_TIME 20int bufferMAX_BUFFER;/*定义

13、数据为生产者*/*定义数据为消费者*/*定义数据为缓存区*/*定义运行时间*/*定义最大缓存区*/int produce_pointer=0,consume_pointer=0;/*定义指针*/sem_t producer_semaphore,consumer_semaphore,buffer_mutex;/*定义信-号量,互斥*/pthread_t threads_pNUM_THREADS_P; /*声明生产者线程 */pthread_t threads_cNUM_THREADS_C; /*声明消费者线程 */FILE* fd;void *producer_thread(void *tid)

14、;/* 声明生产者线程 */void *consumer_thread(void *tid); /*声明消费者线程 */void showbuf(); /* 声明 showbuf 方法*/void handler()int i; /* 定义 i*/for(i=0;iNUM_THREADS_P;i+)pthread_cancel(threads_pi);/*for 循环,如果 iNUM_THREADS_P, 贝U pthread_cancel(threads_pi); 并且 i+*/for(i=0;iNUM_THREADS_C;i+)pthread_cancel(threads_ci);/*fo

15、r 循环,如果 iNUM_THREADS_C,贝U pthread_cancel(threads_ci); 并且 i+*/int main()int i; /* 定义 i*/signal(SIGALRM,handler);/* 定义信号量 */fd=fopen(output.txt,w);/*打开一个文件用来保存结果*/sem_init(&producer_semaphore,0,MAX_BUFFER); /*放一个值名信号灯 */sem_init(&consumer_semaphore,0,0);sem_init(&buffer_mutex,0,1);for(i=0;iMAX_BUFFER;

16、i+)bufferi=0; /* 引发缓冲 */*创建线程*/for(i=0;iNUM_THREADS_P;i+)pthread_create(&threads_pi,NULL,(void*)producer_thread,(void*)(i+1);/*创建线程*/for(i=0;iNUM_THREADS_C;i+)pthread_create(&threads_ci,NULL,(void*)consumer_thread,(void *)(i+1);alarm(RUN_TIME);for(i=0;iNUM_THREADS_P;i+)pthread_join(threads_pi,NULL);

17、/*等待线程退出*/for(i=0;iNUM_THREADS_C;i+)pthread_join(threads_ci,NULL);/*等待线程退出*/sem_destroy(&producer_semaphore);/*清除信号灯*/sem_destroy(&consumer_semaphore);/*清除信号灯*/sem_destroy(&buffer_mutex);/*清除缓存区*/fclose(fd); /* 关闭文件 */return 0;void *producer_thread(void *tid)pthread_setcancelstate(PTHREAD_CANCEL_ENA

18、BLE,NULL);/*设置状态,PTHREAD_CANCEL_ENABLE 是正常处理cancel信号*/while(1) sem_wait(&producer_semaphore); /* 等待,需要生存 */srand(int)time(NULL)*(int)tid);sleep(rand()%2+1); /*一个或两个需要生产*/while(produce_pointer+1)%20=consume_pointer); /*指针位置*/sem_wait(&buffer_mutex); /* 缓存区 */bufferproduce_pointer=rand()%20+1; /*指针位置

19、*/produce_pointer=(produce_pointer+1)%20; /*指针位置*/*判断*/if(produce_pointer=0)printf( 生产者:%d指针指向:%2d生产产品号:2dn,(int)tid,19,buffer19);/*输出生产者,指针,缓存区*/fprintf(fd, 生产者:%d 指针指向:%2d 生产产品 号:2dn,(int)tid,19,buffer19);/*输出生产者,指针,缓存区*/ elseprintf( 生产者:%d指针指向:%2d生产产品号:%2dn,(int)tid,produce_pointer-1,bufferproduc

20、e_pointer-1);/*输出生产者,指针,缓存区 */fprintf(fd, 生产者:%d 指针指向:%2d 生产产品 号:%2dn,(int)tid,produce_pointer-1,bufferproduce_pointer-1);/*输出生产者,指针,缓存区 */showbuf();sem_post(&buffer_mutex);sem_post(&consumer_semaphore); /* 通知消费者缓冲区不是空的 */srand(int)time(NULL)*(int)tid);sleep(rand()%5+1); /*等待几秒钟,然后继续生产*/return (void

21、*)0);void *consumer_thread(void *tid)/*可以被其他线程使用*/pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);/* 设置状态,PTHREAD_CANCEL_ENABLE 是忽略 cancel 信号*/while(1)sem_wait(&consumer_semaphore); /*通知消费者消费 */srand(int)time(NULL)*(int)tid);sleep(rand()%2+1);/*一个或两个来消费 */sem_wait(&buffer_mutex);printf( 消费者:%d指针指

22、向:%2d消费产品号:%2dn,(int)tid,consume_pointer,bufferconsume_pointer);/*输出消费者,消费者指针,缓存区 */fprintf(fd, 消费者:%d指针指向:%2d消费产品号:%2dn,(int)tid,consume_pointer,bufferconsume_pointer);/*输出消费者,消费者指针,缓存区 */bufferconsume_pointer=0; /*消费者指针指向 0*/consume_pointer=(consume_pointer+1)%20;showbuf();sem_post(&buffer_mutex);

23、sem_post(&producer_semaphore); /*通知生产者缓冲区不是空的*/srand(int)time(NULL)*(int)tid);sleep(rand()%5+1); /*等待几秒钟,然后继续消费*/)return (void*)0);)/*查看缓冲区内容*/void showbuf()int i; /* 定义 i*/printf(buffer:);/*输出缓存区 */fprintf(fd,buffer:);/*输出缓存区 */for(i=0;iMAX_BUFFER;i+)printf(%2d ,bufferi);/* 输出缓存区 i*/fprintf(fd,%2d

24、,bufferi); /*输出缓存区 i*/printf(nn);/*换行*/fprintf(fd,nn); /*换行 */实验结果文件()编揖(日 查看(Y)搜索(S)终端(工)帮助出)rootlocal.host 臬面#rootlocalhost 桌面 j#gcc 3.c -o 3 -Ipthread ./3rootlocalhost:/ 桌面生产者:5 缓冲区:1指针指向:60 0 0 0生产产品号:10 0 0 0 0生产者:3卷神区:1指针指向:112 0 e e生产产品号:120 0 0 0 0生产者:1 绦神区:1指针指向:212 19 0 0生产产品号:19o e o e e生

25、产者:4线神区:1指针指向:312 19 19 0生产产品号:190 0 0 0生产青:2领神区:1指针指向:412 19 19 9生产产品号:0 0 0 0,消费者:1线神区:0指针指向:012 19 19 9消费产品号:0 e o e津费者:2线冲区:0指针指向:1 0 19 19 9消费产品号:120 0 0 0 0造费者:3绥神区:0指针指向:20 0 19 9消费产品号:190 0 0 0 0消费者:4 绥神区:。指针指向:30 0 0 9消费产品号:190 0 0 0港费者:5 镁神区:指针指向:40 0 0 0消费产品号:0 0 0 0生产者:1 缘神区:。指针指向:5e e e

26、 e 18生产产品号:18o e o e生产者:5线神区:0指针指向:60 0 0 0 18生产产品号:10 0 0文件(E)编辑(E)查看Q)搜索(S)终端(工)帮助(H)生产者:3缓冲区:0指针指向:80 0 0 0生产产品号:90 6 9 0生产者:2 缓冲区:。指针指向:90 0 0 0生产产品号:0 6 9 9消费者:2缓冲区:。指针指向:70 0 0 0消费产品号:0 0 9 9消费者:4缓神区:0指针指向:80 0 0 0消费产品号:0 0 0 9生产者:1 缓冲区:。指针指向:100 0 0 0生产产品号:1717消费者:3缓神区:0指针指向:90 0 0 0消费产品号:e e

27、 e o917生产者:3 缓冲区:。指针指向:H0 0 0 0生产产品号:130 0 0 0 1713生产者:4缓神区:0指针指向:120 0 0 0生产产品号:120 0 0 0 171312生产者:5缓冲区:0指针指向:130 0 0 0生产产品号:180 0 0 0 17131218生产者:2缓神区:0指针指向:140 0 0 0生产产品号:12e e 0 o 1713121812消费者:2 缓冲区:。指针指向:ie0 0 0 0消费产品号:170 0 0 0 0131812消费者:5缓神区:0指针指向:116 0 0 0消费产品号:136 0 0 0 0121812消费者:4缓冲区:0

28、指针指向:120 0 0 0消费产品号:120 0 0 0 01812.结论本次课程设计主要是对操作系统中线程,进程同步互斥等知识的揉合应用, 生产者-消费者问题是一个著名的同步问题,原理易懂,但操作并不简单。本次 编写的程序基本实现了设计要求的功能,但并没有做到真正的完善,系统还有一 点小瑕疵,对于某些方面的小问题没有能解决。 但这次课程设计通过我们组员的 努力还是基本完成了,对于自身的帮助非常大,无论是编写程序还是设计等各方 面都有很大的提升。.收获、体会和建议经过2.5天的课程设计,我们完成了一个生产者-消费者问题的小程序,这 个程序主要考察的是是P、V操作,实验设一个共享缓冲区,生产者和消费者互 斥的使用,当一个线程使用缓冲区的时候,另一个让其等待直到前一个线程释放 缓冲区为止。还有就是对进程,线程的操作。实

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论