




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、精选优质文档-倾情为你奉上齐齐哈尔大学操作系统课程综合实践题目:多进程同步方法解决生产者消费者问题班级:0姓名:0 学号:0指导教师:0 2011年12 月7日综合实践评分表班级0姓名0指导教师0题目:多进程同步方法解决生产者消费者问题 评分标准评分标准分数权重评分的依据得分AC选题10选题符合大纲要求,题目较新颖,工作量大选题基本符合大纲要求,工作量适中工作态度10态度端正,能主动认真完成各个环节的工作,不迟到早退,出勤好。能够完成各环节基本工作,出勤较好。存储结构、算法描述20能正确选择存储结构,定义准确,算法流程图或类C语言描述的算法准确无误能正确选择存储结构,算法流程图或类C语言描述的
2、算法基本准确独立解决问题的能力10具有独立分析、解决问题能力,有一定的创造性,能够独立完成软件的设计与调试工作,程序结构清晰,逻辑严谨,功能完善。有一定的分析、解决问题能力。能够在老师指导下完成软件的设计与调试工作,程序功能较完善。答辨问题回答20能准确回答老师提出的问题能基本准确回答老师提出的问题程序运行情况10程序运行正确、界面清晰,测试数据设计合理。程序运行正确、界面较清晰,能给出合适的测试数据。综合实践报告20格式规范,层次清晰,设计思想明确,解决问题方法合理,体会深刻。格式较规范,设计思想基本明确,解决问题方法较合理。总分指导教师(签字): 注:介于A和C之间为B级,低于C为D级和E
3、级。按各项指标打分后,总分在90100为优,8089为良,7079为中,6069为及格,60分以下为不及格。多进程同步方法解决生产者消费者问题摘要:本文论述了多进程同步方法解决生产者消费者问题的过程。该程序使学生对操作系统的工作机制有了初步的了解,其主要目的是使学生了解和撑握在Linux系统平台下的C语言编程,用来解决实现生活中遇到的问题。并以Linux系统开发平台,以及虚拟机来实现。关键字:生产者消费者问题,Linux系统平台,虚拟机,信号量,线程(thread)专心-专注-专业多进程同步方法解决生产者消费者问题一、课程设计所需设备计算机一台,Red Hat linux9.03系统一套。二、
4、课程设计预期目的通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制。三、课程设计任务用多进程同步方法解决生产者-消费者问题设计目的:通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制.说明:有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1-20这20个整型数.设计要求:1) 每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者线程的标识符.2) 生产者和消费者各有两个以上.3) 多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码.四、课程设计基本思想多进程是一种非常简洁的多任务操作方式。在L
5、inux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种烦琐的多任务工作方式。生产者-消费者方案是多进程应用程序开发中最常用的构造之一。因此困难也在于此。因为在一个应用程序中可以多次重复生产者-消费者行为,其代码也可以如此。设计中创建了 Consumer 类,该类通过在一些多进程应用程序中促进代码重用以及简化代码调试和维护来解决这个问题。多进程应用程序通常利用生产者-消费者编程方案,其中由生产者进程创建重复性作业,将其传递给作业队列,然后由消费者进程处理作业。多进程是一种使应用程序能同时处理多个操作的编程技术。通常有两种不同类型的多
6、进程操作使用多个进程:适时事件,当作业必须在特定的时间或在特定的间隔内调度执行时;后台处理,当后台事件必须与当前执行流并行处理或执行时;适时事件的示例包括程序提醒、超时事件以及诸如轮询和刷新之类的重复性操作。后台处理的示例包括等待发送的包或等待处理的已接收的消息。生产者-消费者方案很适合于后台处理类别的情况。这些情况通常围绕一个作业“生产者”方和一个作业“消费者”方。当然,关于作业并行执行还有其它考虑事项。在大多数情况下,对于使用同一资源的作业,应以FCFS的方式按顺序处理,这可以通过使用单进程的消费者轻松实现。通过使用这种方法,使用单个进程来访问单个资源,而不是用多个进程来访问单个资源。要启
7、用标准消费者,当作业到来时创建一个作业队列来存储所有作业。生产者进程通过将新对象添加到消费者队列来交付这个要处理的新对象。然后消费者进程从队列取出每个对象,并依次处理。当队列为空时,消费者进入休眠。当新的对象添加到空队列时,消费者会醒来并处理该对象。五详细设计5.1、调试问题分析为解决生产者/消费者问题,应该设置两个资源信号量,其中一个表示空缓冲区的数目,用Full表示,其初始值为有界缓冲区的大小BUFFER_NUM;另一个表示缓冲区中产品的数目,用Empty表示,其初始值为0。另外,由于有界缓冲区是一个临界资源,必须互斥使用,所以还需要再设置一个互斥信号量Mutex,起初值为1。 在生产者/
8、消费者问题中,信号量实现两种功能。首先,它是生产产品和消费产品的计数器,计数器的初始值是可利用的资源数目(有界缓冲区的长度)。其次,它是确保产品的生产者和消费者之间动作同步的同步器。 生产者要生产一个产品时,首先对资源信号量Full和互斥信号量Mutex进行P操作,申请资源。如果可以通过的话,就生产一个产品,并把产品送入缓冲区。然后对互斥信号量Mutex和资源信号量Empty进行V操作,释放资源。 消费者要消费一个产品时,首先对资源信号量Empty和互斥信号量Mutex进行P操作,申请资源。如果可以通过的话,就从缓冲区取出一个产品并消费掉。然后对互斥信号量Mutex和资源信号量Full进行V操
9、作,释放资源。如果缓冲区中已经没有可用资源,就把申请资源的进程添加到等待队列的队尾。如果有一个资源被释放,在等待队列中的第一个进程被唤醒并取得这个资源的使用权。 5.2、程序流程图生产者线程开始资源信号量P操作互斥信号量P操作生产一个产品把产品送入缓冲区互斥信号量V操作资源信号量V操作等待队列中有消费者线程等待队列中有消费者线程线程自我阻塞添加到等待队列线程自我阻塞添加到等待队列未通过未通过通过通过唤醒对头的消费者线程唤醒对头的消费者线程生产者线程结束YYNN图一 生产者流程结构消费者线程开始资源信号量P操作互斥信号量P操作从缓冲区取出一个产品消费一个产品互斥信号量V操作资源信号量V操作等待队
10、列中有生产者线程等待队列中有生产者线程线程自我阻塞添加到等待队列线程自我阻塞添加到等待队列未通过未通过通过通过唤醒对头的生产者线程唤醒对头的生产者线程消费者线程结束YYNN图二 消费者流程结构5.3、程序自定义函数1、void produce(struct sem_info * );这个函数是生产者进行的生产过程,为所有的生产者所共享。结构体指针用来接收生产者线程创建时传来的生产者的个人信息。2、void consumer(struct sem_info * );这个函数是消费者进行的生产过程,为所有的消费者所共享。结构体指针用来接收消费者线程创建时传来的消费者的个人信息。3、void set
11、produce(void); 这个函数是用来设置生产者的个数和他们的名字。4、void setconsumer(void);这个函数是用来设置消费者的个数和他们的名字。5、void activepthread(int);这个函数是用来创建生产者线程,int型参数为生产者的个数。6、void activecthread(int);这个函数是用来创建生产者线程,int型参数为生产者的个数。7、int gettime(void);这个函数返回来一个整数,作为线程的sleep()函数的参数。8、void myscanf(void);这个函数用来获取设置生产者和消费者的个数时的整数,确保这个数字在0到M
12、AX_BUFFER之间。5.4、系统函数调用线程Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。Linux下pthread的实现是通过系统调用clone()来实现的。clone()是Linux所特有的系统调用,它的使用方式类似fork。函数pthread_create用来创建一个线程,它的原型为:extern int pthread_create _P (pthread_t *_thread, _const pthread_attr_t *_attr,void *(*_
13、start_routine) (void *), void *_arg);第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。第二个参数我们也设为空指针,这样将生成默认属性的线程。当创建线程成功时,函数返回0,若不为0则说明创建线程失败,常见的错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。函数pthread_join用来等待一个线程的结束。函数
14、原型为:extern int pthread_join _P (pthread_t _th, void *_thread_return);第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。一个线程的结束有两种途径,一种是函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。它的函数原型为:extern void pthread_exit _P (void *_retval) _attribute_ (
15、_noreturn_);唯一的参数是函数的返回代码,只要pthread_join中的第二个参数thread_return不是NULL,这个值将被传递给 thread_return。最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码ESRCH。信号量信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。当公共资源增加时,调用函数sem_post()增加信号量。只有当信号量值大于时,才能使用公共资源,使用后,函数sem_wait()减少信号量。函数sem_trywait()和函数pthread_ mute
16、x_trylock()起同样的作用,它是函数sem_wait()的非阻塞版本。它们都在头文件 /usr/include/semaphore.h中定义。信号量的数据类型为结构sem_t,它本质上是一个长整型的数。函数sem_init()用来初始化一个信号量。它的原型为:extern int sem_init _P (sem_t *_sem, int _pshared, unsigned int _value);sem为指向信号量结构的一个指针;pshared不为时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。函数sem_post( sem_t *sem
17、)用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。函数sem_destroy(sem_t *sem)用来释放信号量sem。六源程序清单6.1、源程序#include #include #include #include typedef HANDL
18、E Semaphore; / 信号量的Windows原型 #define P(S) WaitForSingleObject(S,INFINITE) / 定义Windows下的P操作 #define V(S) ReleaseSemaphore(S,1,NULL) / 定义Windows下的V操作 #define rate 1000 #define CONSUMER_NUM 2 /* 消费者个数 */ #define PRODUCER_NUM 3 /* 生产者个数 */ #define BUFFER_NUM 20 /* 缓冲区个数 */ char *thing8 = 鸡腿堡, 薯条, 可乐, 三明
19、治, 面包, 小笼包, 火腿,馒头; /生产和消费的产品名称 struct Buffer int productBUFFER_NUM; / 缓冲区 int start,end; / 两个指针相当于教材中的 in out 指针 g_buf; Semaphore Empty,Full,Mutex; /分别相当于Empty, Full, Mutex三个信号量 /* 消费者线程*/ DWORD WINAPI Consumer(LPVOID para) / i表示第i个消费者 int i = *(int *)para; /利用para传入当前消费者的编号 int ptr; / 待消费的内容的指针 pri
20、ntf(消费者%1d: 需要资源n, i); int j=0; while (j+4) / 等待产品 P(Full); / 有产品,先锁住缓冲区 P(Mutex); / 记录消费的物品 ptr=g_buf.start; / 再移动缓冲区指针 g_buf.start= (g_buf.start+1)%BUFFER_NUM; /让其他消费者或生产者使用 printf( 消费者%01d: 我需要buf%d=%sn,i, ptr, thingg_ductptr); /消费完毕,并释放一个缓冲 printf( 消费者%01d: 我消费完毕%sn, i,thingg_ductp
21、tr); V(Mutex); V(Empty); Sleep(rate*rand()%10+110); return 0; /* 生产者线程*/ DWORD WINAPI Producer(LPVOID para) int i = *(int *)para - CONSUMER_NUM; int ptr; int data; /产品 int j=0; while(j+4) data=rand()%8; printf(生产者%01d: 生产出: %s!n,i,thingdata); /等待存放空间 P(Empty); /有地方,先锁住缓冲区 P(Mutex); /记录消费的物品 ptr=g_bu
22、f.end; /再移动缓冲区指针 g_buf.end =(g_buf.end+1)%BUFFER_NUM; printf(生产者%01d: 放到缓冲区 buf%d=%sn,i,ptr,thingdata); g_ductptr=data; /放好了完毕,释放一个产品 /让其他消费者或生产者使用 V(Mutex); V(Full); Sleep(rate/2*rand()%10+110); return 0; int main(int argc,char *argv) /线程技术,前面为消费者线程,后面为生产者线程 HANDLE hThreadCONSUMER_NUM+PRODUC
23、ER_NUM; / 线程计数 srand(time(NULL); rand(); DWORD tid; int i=0; /初始化信号量 Mutex=CreateSemaphore(NULL,1,1,MutexOfConsumerAndProducer); Empty=CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, BufferSemaphone); Full=CreateSemaphore(NULL,0,BUFFER_NUM,ProductSemaphone); if(!Empty|!Full|!Mutex) printf(Create Semap
24、hone Error!n); return -1; int totalThreads=CONSUMER_NUM+PRODUCER_NUM; /开启消费者线程 printf(先请消费者上席!n); for(i=0;iCONSUMER_NUM; i+) hThreadi=CreateThread(NULL, 0, Consumer, &i,0,&tid); if(hThreadi)WaitForSingleObject(hThreadi,10); printf(生产者就位!n); for(;itotalThreads;i+) hThreadi=CreateThread(NULL,0,Producer,&i,0,&tid); if(hThreadi)WaitForSingleObject(hThreadi,10); /生产者和消费者的执行 WaitForMultipleObjects(totalThreads,hThread,TRUE,INFINITE); return 0; 6.2、编译及运行结果在程序中设置了两个消费者,三个生产者,为便于描述出生产-消费的过程,我用食物代表被缓冲区消费的资源。在实验结果中我们可以看到
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024成都工贸职业技术学院辅导员招聘笔试真题
- 2025年板栗机械化剥壳去衣机项目发展计划
- 第3课时 按比分配教案 人教版数学六年级上册
- 2024年新疆维吾尔自治区消防救援总队招录消防员真题
- 2025年内蒙古事业单位招聘考试笔试试题【答案】
- 消费信贷对消费行为的影响分析
- 消防员工作汇报
- 项目洞室开挖施工安全防护措施
- 电话客服实习报告范文4篇
- 2025年物理特性分析产品项目建议书
- 传感器与机器视觉 课件 第六章 机器视觉
- 2019疏浚工程预算定额
- RFC2326(中文版+英文版+可链接目录)-RTSP
- 2023八年级历史下册第六单元科技文化与社会生活第18课科技文化成就说课稿新人教版
- 2023新能源光伏电站检修规程
- 特种作业人员体检表
- 2016电动汽车充换电服务网络运营管理系统通信规约:系统与站级监控系统通信规约
- 知识产权技术部内审核查表含审核记录
- 租船运输实务与法律航次租船合同
- 火电厂基本建设程序与设计内容深度介绍
- 古诗词九宫格题目课件
评论
0/150
提交评论