操作系统生产者与消费者课程设计 (1)

合集下载

操作系统课程设计 生产者与消费者

操作系统课程设计 生产者与消费者

燕山大学课程设计说明书课程设计名称:操作系统OS题目:多道程序缓冲区协调操作班级:开发小组名称:课题负责人:课题组成员:姓名学号班级自评成绩课题开发日期:一、概述利用MFC类库编写一个可实现多道程序缓冲区协调操作的面向对象的程序。

1.1基本功能演示生产者消费者程序,多线程并发执行的过程;可以控制生产者消费者的个数及生产者生产的速度和消费者的速度,进度条中显示Buffer 中数据的个数,有五个按钮,分别为:开始、继续,暂停、结束、退出,点击开始按钮,程序开始执行,点击暂停按钮,所有线程暂停执行,点击继续按钮,线程继续执行,结束按钮使得所有线程结束执行,点击退出按钮,退出系统,统计按钮按下时显示此时的Buffer1,buffer2的生产者生产的次数和Buffer3的消费者消费的次数,及Move的次数,和开始时间及结束时间。

1.2开发计划10号查阅参考资料,了解整体的框架结构; 11号完成整体模块的构思及设计; 12号完成程序具体的编写任务并调试代码; 13号整理总结并书写报告; 14号验收。

1.3人员分工1.4环境、工具和开发方法本程序在XP系统下,采用的开发语言是C++,它是一种使用非常广泛的面向对象的计算机编程语言。

它支持过程化程序设计、数据抽象、面向对象程序设计、制作图标等多种程序设计风格。

在Visual C++ 6.0编程环境中,利用MFC类库编写C++风格的应用程序,基于MFC类库的应用程序可以快速建立起应用程序,并且类库为我们提供了大量的封装类。

二、需求分析用户需要看到看到并发程序的运行过程,以及能对过程进行控制,可以设计几个按钮控制开始,暂停、结束等功能,并可以让用户自定义生产者消费者数量及生产者消费者线程并发执行的速度,并能以用户能够明白的形式表示出来,可以设计一个进度条显示各个Buffer中的物品数量,并用数字显示出来,看的就清楚了,设置一个统计按钮,当用户点击按钮时,就可以获取当前各个线程的情况,有几个线程在执行,Buffer1的线程个数,Buffer2的线程个数及从开始到结束所用的时间,从而了解线程运行的情况。

生产者消费者课程设计

生产者消费者课程设计

生产者消费者课程设计一、课程目标知识目标:1. 学生理解生产者与消费者的基本概念,掌握它们在生态系统中的作用与相互关系。

2. 学生能够描述食物链与食物网的结构,并识别其中的生产者和消费者。

3. 学生了解生态系统中物质与能量的流动过程。

技能目标:1. 学生能够通过观察与实验分析,识别并区分生态系统中的生产者和消费者。

2. 学生具备绘制食物链和食物网的能力,并能用其解释生态系统中物质能量的传递。

3. 学生能够运用所学知识解决有关生产者消费者的实际问题。

情感态度价值观目标:1. 学生培养对生态系统的尊重与保护意识,认识到生产者消费者在其中的重要角色。

2. 学生通过学习小组合作,增强团队协作意识,培养科学探究精神。

3. 学生在探索生态学知识的过程中,激发对生命科学的好奇心与学习兴趣,形成积极的学习态度。

课程性质分析:本课程为生态学基础知识教学,通过讲解生产者与消费者的概念,使学生建立对生态系统基本构成的理解,并培养其分析和解决实际生态问题的能力。

学生特点分析:考虑到学生所在年级,已具备一定的观察、思考与自主学习能力,对新知识充满好奇心,但可能缺乏将理论知识应用于实际情境的经验。

教学要求:1. 教学内容紧密结合课本知识,以实例进行引导,提高学生对概念的理解。

2. 教学过程注重启发式教学,引导学生主动探究,提高其分析问题和解决问题的能力。

3. 教学评价关注学生的过程表现,强调知识的应用与实践,以及情感态度价值观的培养。

二、教学内容本课程依据课程目标,结合课本第三章“生态系统的结构与功能”相关内容,进行以下教学安排:1. 引入生态系统的基本概念,重点讲解生产者与消费者的定义、特点及作用。

- 教材章节:第三章第一节“生态系统的基本概念”2. 通过案例分析,使学生掌握食物链与食物网的结构,并理解其中的物质能量流动。

- 教材章节:第三章第二节“食物链与食物网”3. 介绍生态系统中物质与能量的转化过程,分析生产者与消费者在其中的角色。

生产者和消费者课程设计

生产者和消费者课程设计
2、数据结构及信号量定义的说明;
3、实验的步骤;
4、实验源程序关键算法;
5、实验运行图;
6、实验结果分析;
六、结论(应当准确、完整、明确精练;也可以在结论或讨论中提出建议、设想、尚待解决问题等。)
七、参考文献
八、指导教师评语
签名:
年月日
课程设计成绩
附:1、课程设计的填写请按格式要求做;
2、文字内容宋体、五号、1.5倍行距;
2、培养学生能够独立进行知识综合,独立开发较大程序的能力。
3、培养提高学生软件开发能力和软件的调试技术。
4、培养学生开发大型程序的方法和相互合作的精神。
5、培养学生的创新意识。
6、培养学生的算法设计和算法分析能力。
7、培养学生对问题进行文字论述和文字表达的能力。
二、课程设计的内容及其要求
1、可利用临界区(CCriticalSection)、事件(CEvent)、信号量(CSemaphore)来实现进程的同步。
2、根据生产者和消费者问题的特性做好软件实现的需要分析。
3、可根据问题的实际需要,来改变对信号量的使用及数量和初值的赋值。
4、当系统运行时,能直观地、动态地反映当前线程运行的状态和信号量的变化。
5、要求系统能满足能多进程的并发与互斥。
6、要求在系统安全状态的前提下,兼顾各个进程的公平。
三、课程设计的时间安排
3、程序代码字体Times New Roman,五号、1.5倍行距;
《操作系统》课程设计
生产者和消费者问题实践
系院:信息工程学院
学生姓名:xxxxxxx
学号:xxxxxxxxxxxx
专业:xxxxxxxxxxxx
年级:xxxxxxx
完成日期:xxxx年xx月

生产者--消费者同步问题的算法实现

生产者--消费者同步问题的算法实现
); } } char prodt[3]= {'a','b','c'}; int main(int argv,char* argc[]) { pthread_t prd[PRD],csm[CSM]; //初始化信号量 sem_init(&pool,0,PSZ); sem_init(&iterms,0,0); sem_init(&mutex,0,1); //创建生产者线程 for(int i=0; i<PRD; ++i) pthread_create(&prd[i],NULL,prod,(void*)&prodt[i]); // 创 建 消费者线程 for(int i=0; i<CSM; ++i) pthread_create(&csm[i],NULL,coms,NULL); sem_t mn; sem_init(&mn,0,0); p(mn); }
{ while(1) { p(pool); p(mutex); pdt.push(*((char*)argv)); cout<<"生产者产生一个数据:"<<*((char*)argv)<<endl; v(mutex); v(iterms); } } //消费者线程 void* coms(void*argv) { char tem; while(1) { p(iterms); p(mutex); tem=pdt.front(); pdt.pop(); cout<<"消费者消耗一个数据:"<<tem<<endl;
放消息 取消息
P

生产者消费者问题操作系统课程设计

生产者消费者问题操作系统课程设计

目录1 绪论 (3)1.1 实现的功能 (3)1.2 P V 操作 (3)2 生产者——消费者问题。

(4)2.1 要求 (4)2.2 生产者和消费者两个进程的程序 (4)2.3进程控制块PCB。

(5)2.4处理器的模拟。

(5)2.5程序设计 (6)3设计步骤 (7)3.1课程分析 (7)3.1.2 流程图 (7)3.1.3 测试程序 (9)3.1.4测试结果分析 (14)5 结论 (15)参考文献 (16)1 绪论生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。

模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语——同步原语——所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

1.1 实现的功能生产者-消费者问题是一个经典的进程同步问题,有m个生产者和n个消费者,它们共享可存放k件产品的缓冲区。

生产者进程生产物品,然后将物品放置在一个空缓冲区中,供消费者进程消费。

消费者进程从缓冲区中获得物品,然后释放缓冲区。

当生产者进程生产物品时,如果没有空缓冲区可用,那么生产者进程必须等待消费者线程释放出一个空缓冲区。

当消费者进程消费物品时,如果没有满的缓冲区,那么消费者进程将被阻塞,直到新的物品被生产出来。

1.2 P V 操作(1) PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P (s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

操作系统课程设计“生产者-消费者”问题

操作系统课程设计“生产者-消费者”问题

《操作系统》课程设计题目:“生产者-消费者”问题学院:信息工程学院专业:计算机科学与技术班级:计科1302*名:***指导老师:***2016年1月 15日目录一、课程设计目标 (2)二、课题内容 (2)1.实验目的 (2)2、实验环境 (2)3、实验要求 (2)三、设计思路 (3)1.信号量的设置 (3)2.系统结构 (4)3.程序流程图 (5)4.P V操作代码 (6)四、源代码 (7)五、运行与测试 (10)六、心得体会 (12)一、课程设计目标学习System V的进程间通信机制,使用信号量和共享内存实现经典进程同步问题“生产者-消费者”问题。

具体要求:1.创建信号量集,实现同步互斥信号量。

2.创建共享内存,模拟存放产品的公共缓冲池。

3.创建并发进程,实现进程对共享缓冲池的并发操作。

二、课题内容1.实验目的(1)掌握基本的同步互斥算法,理解生产者和消费者同步的问题模型。

(2)了解linux中多线程的并发执行机制,线程间的同步和互斥。

2、实验环境:C/C++语言编译器3、实验要求(1)创建生产者和消费者线程在linux环境下,创建一个控制台进程,在此进程中创建n个线程来模拟生产者或者消费者。

这些线程的信息由本程序定义的“测试用例文件”中予以指定。

(2)生产和消费的规则在按照上述要求创建线程进行相应的读写操作时,还需要符合以下要求:①共享缓冲区存在空闲空间时,生产者即可使用共享缓冲区。

②从上边的测试数据文件例子可以看出,某一生产者生产一个产品后,可能不止一个消费者,或者一个消费者多次地请求消费该产品。

此时,只有当所有的消费需求都被满足以后,该产品所在的共享缓冲区才可以被释放,并作为空闲空间允许新的生产者使用。

③每个消费者线程的各个消费需求之间存在先后顺序。

例上述测试用例文件包含一行信息“5 C 3 l 2 4”,可知这代表一个消费者线程,该线程请求消费1,2,4号生产者线程生产的产品。

而这种消费是有严格顺序的,消费1号线程产品的请求得到满足后才能继续往下请求2号生产者线程的产品。

现代操作系统课程设计报告 生产者与消费问题

进程同步模拟设计——生产者和消费者问题第一章课设任务本课程设计的任务在于,通过编写一个具体的有关操作系统进程同步互斥的经典问题,加强对操作系统实现进程间同步与互斥的机制的理解。

同时培养提出问题、发现知识、使用工具、解决问题的能力。

具体地,我们要编制出一个程序,利用PV原语以及进程创建、同步、互斥、销毁等相关的系统调用来模拟“生产者—消费者”问题。

第二章背景介绍2.1 “生产者—消费者”问题(the producer-consumer problem)生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。

其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。

问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。

同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。

问题分析:该问题涉及到操作系统进程管理当中的两个重要概念——同步和互斥。

同步,表现在生产者和消费者需要协同工作,步调不能拉开太大(由缓冲区大小n决定,n越大,缓冲空间越大,步调可以拉得越开;n=1时,必须是生产一个,消费一个,生产者和消费者就完全同步了)。

当步调差距超过极限时,走在前面的当前进程(生产者)调用P 原语时由于资源耗尽,被阻塞;步调靠后的继续向前推进。

由此实现同步。

互斥,表现在生产者与消费者、生产者与生产者、消费者与消费者任何两个成员之间必须互斥地使用缓冲区。

当有一个成员进入缓冲区存/取产品时,其他成员将被关在门外排队等候(被阻塞);当完毕时,通知队首成员进入。

由操作系统理论可知,我们需要三个信号量,分别命名full, empty, mutex,来分别代表消费者的可用资源数、生产者的可用资源数、缓冲区是否可用。

计算机操作系统课程设计报告《生产者---消费者问题》

计算机操作系统课程设计报告《生产者---消费者问题》《计算机操作系统》课程设计题目:生产者---消费者问题专业:软件工程年级:2010级小组成员: A B指导教师:时间:地点:2012年5 月摘要生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。

该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。

生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。

与此同时,消费者也在缓冲区消耗这些数据。

该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。

生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

目录1. 概述 (4)2. 课程设计任务及要求 (4)2.1 设计任务 (4)2.2 设计要求 (4)2.3 分工日程表 (4)3. 算法及数据结构 (5)3.1算法的总体思想 (5)3.2 生产者模块 (5)3.3 消费者模块 (7)4. 程序设计与实现 (8)4.1 程序流程图 (8)4.2 程序代码 (9)4.3 实验结果 (14)5. 结论 (17)6. 收获、体会和建议 (17)6.1收获......................................... 错误!未定义书签。

7. 参考文献 (18)1. 概述本课题设计是完成了“操作系统原理”课程进行的一次全面的综合训练,通过这次课程设计,充分检验学生对课程的掌握程度和熟练情况,让学生更好的掌握操作系统的原理及其实现方法,加深对课程的基础理论和算法的理解,加强学生的动手能力。

生产者消费者问题——操作系统课程设计—方案汇报PPT


设计生产者、 消费者数目, 及缓冲区大小
点击开始模拟
观察模拟情况,按需要 调整生产或消费速度 点击分析按钮 查看统计分析数据
退出系统
结构设计(1):
在本模拟系统中,使用者需要设定生产者个数, 消费者个数,期间用户可以选择改变两者的相对速度来进行测试,观察结果是否为 预测结果。最后,使用者还可以点击分析按钮进行实验结果统计分析。
P线程
如果缓冲区不满
缓 冲 区
C线程
P、C线程访问缓 冲区受互斥信号量 mutex控制
如果缓冲区不空
进度安排:
• 寒假期间:确定课题项目,商讨选用何种设计语 言,完成程序框架及基本结构和类的整体设计。 • 2月20日—3月1日:完成设计考核幻灯片的制作, 完成各类方法的编写,完成核心程序并进行基本 测试。 • 3月2日—3月5日:完善核心程序,优化数据结构, 初步进行图形化界面的编写。 • 3月6日—3月10日:完成用户界面程序并进行测试 和改进。完成期间各个总结汇报幻灯片。 • 3月11—结束:综合测试,撰写总结汇报。提交论 文。
创新之处:
• (1)采用Java程序设计语言,其多线程程序设 计可模拟操作系统的并发环境 • (2)用Java中的wait()和notify()来模拟P、V操作 • (3)用进度条和滑动竿比较形象和准确的描述模 拟结果。
“生产者—消费者”问题的模拟系统
操作系统课程设计
目的及意义
通过模拟经典的“生产者—消费者问题”,巩 固在操作系统原理课上所学的知识,加深对操作 系统中实现同步、互斥。并发的方法、临界区管 理等问题的认识和理解,同时了解软件设计的流 程、方法以及思想,提高分析设计以及编程的能 力。
功能设计:
开始界面

操作系统生产者与消费者课程设计

操作系统课程设计课题名称:Windows OS平台下的生产者和消费者问题班级:软件学号:姓名:指导教师:成绩:目录一、课程设计目的 (1)二、课程任务描述 (1)三、技术方案 (1)1. 算法分析 (1)2. 技术机制 (4)3. 库函数介绍 (5)4. 运行环境 (7)四、详细设计 (7)1.程序框架 (8)2.数据结构 (10)3. 流程图 (10)五、运行与测试 (11)六、总结及改进意见 (11)七、附录 (11)一、课程设计目的1.理解生产者消费者模型,掌握基本的同步、互斥算法。

2.理解操作系统中进程间通信机制IPC3.掌握以生产者/消费者模型为依据,在Windows环境下创建一个控制台进程,实现进程(线程)的同步与互斥。

4.掌握和使用共享主存实现进程间通信机制。

二、课程任务描述设计一个C+程序,该程序通过线程并发机制创建两类线程,分别是消费者线程和生产者线程,并运用IPC机制,在Windows平台下,使用信号量和共享内存实现“生产者-消费者”问题。

具体要求:1.使用IPC机制创建信号集,实现”生产者-消费者“问题中的同步与互斥。

2.使用IPC机制创建共享内存,模拟存放产品的公共缓冲区。

3.以生产者/消费者模型为依据,在Windows环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。

三、技术方案1.算法分析1)创建生产者和消费者线程for(i =0;i< (int) n_Thread;i++){if(Thread_Info[i].entity =='P')h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(Thread_Info[ i]),0,NULL);elseh_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),& (Thread_Info[i]),0,NULL);}2)生产者进程void Produce(void *p){//局部变量声明;DWORD wait_for_semaphore,wait_for_mutex,m_delay;int m_serial;//获得本线程的信息;m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);Sleep(m_delay);//开始请求生产printf("Producer %2d sends the produce require.\n",m_serial);//确认有空缓冲区可供生产,同时将空位置数empty减1;用于生产者和消费者的同步;wait_for_semaphore = WaitForSingleObject(empty_semaphore,-1);//互斥访问下一个可用于生产的空临界区,实现写写互斥;wait_for_mutex = WaitForSingleObject(h_mutex,-1);int ProducePos = FindProducePosition();ReleaseMutex(h_mutex);//生产者在获得自己的空位置并做上标记后,以下的写操作在生产者之间可以并发;//核心生产步骤中,程序将生产者的ID作为产品编号放入,方便消费者识别;printf("Producer %2d begin to produce at position %2d.\n",m_serial,ProducePos);Buffer_Critical[ProducePos] = m_serial;printf("Producer %2d finish producing :\n ",m_serial);printf(" position[ %2d ]:%3d \n" ,ProducePos,Buffer_Critical[ProducePos]);//使生产者写的缓冲区可以被多个消费者使用,实现读写同步;ReleaseSemaphore(h_Semaphore[m_serial],n_Thread,NULL);}3)消费者进程void Consume(void * p){//局部变量声明;DWORD wait_for_semaphore,m_delay;int m_serial,m_requestNum; //消费者的序列号和请求的数目;int m_thread_request[MAX_THREAD_NUM];//本消费线程的请求队列;//提取本线程的信息到本地;m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);m_requestNum = ((ThreadInfo *)(p))->n_request;for (int i = 0;i<m_requestNum;i++)m_thread_request[i] = ((ThreadInfo*)(p))->thread_request[i];Sleep(m_delay);//循环进行所需产品的消费for(i =0;i<m_requestNum;i++){//请求消费下一个产品printf("Consumer %2d request to consume %2d product\n",m_serial,m_thread_request[i]);//如果对应生产者没有生产,则等待;如果生产了,允许的消费者数目-1;实现了读写同步;wait_for_semaphore=WaitForSingleObject(h_Semaphore[m_thread_request[i]],-1);//查询所需产品放到缓冲区的号int BufferPos=FindBufferPosition(m_thread_request[i]);//开始进行具体缓冲区的消费处理,读和读在该缓冲区上仍然是互斥的;//进入临界区后执行消费动作;并在完成此次请求后,通知另外的消费者本处请求已//经满足;同时如果对应的产品使用完毕,就做相应处理;并给出相应动作的界面提示;该相应处理指将相应缓冲区清空,并增加代表空缓冲区的信号量;EnterCriticalSection(&PC_Critical[BufferPos]);printf("Consumer%2d begin to consume %2d product \n",m_serial,m_thread_request[i]);((ThreadInfo*)(p))->thread_request[i] =-1;if(!IfInOtherRequest(m_thread_request[i])){Buffer_Critical[BufferPos] = -1; //标记缓冲区为空;printf("Consumer%2d finish consuming %2d:\n ",m_serial,m_thread_request[i]);printf(" position[ %2d ]:%3d \n" ,BufferPos,Buffer_Critical[BufferPos]);ReleaseSemaphore(empty_semaphore,1,NULL);}else{printf("Consumer %2d finish consuming product %2d\n ",m_serial,m_thread_request[i]);}//离开临界区LeaveCriticalSection(&PC_Critical[BufferPos]);}}2.技术机制有一个有限缓冲区和多个线程:生产者和消费者。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《操作系统》课程设计生产者和消费者问题系院:计算机科学系学生姓名:孙鑫学号:11095114专业:计算机科学与技术年级:二年级完成日期:2013年6月一、课程设计的性质与任务1、生产者-消费者问题是很经典很具有代表性的进程同步问题,计算机中的很多同步问题都可抽象为生产者-消费者问题,通过本实验的练习,希望能加深学生对进程同步问题的认识与理解。

2、熟悉VC的使用,培养和提高学生的分析问题、解决问题的能力。

二、课程设计的内容及其要求1.实验内容以生产者/消费者模型为依据,在Windows 2000环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。

2.实验要求●学习并理解生产者/消费者模型及其同步/互斥规则;●学习了解Windows同步对象及其特性;●熟悉实验环境,掌握相关API的使用方法;●设计程序,实现生产者/消费者进程(线程)的同步与互斥;●提交实验报告。

三、课程设计的时间安排课程设计时间8课时四、课程设计的实验环境本实验是在winxp+VC6.0环境下实现的,利用Windows SDK编制实例程序。

所以试验需要在windows下安装VC后进行。

VC是一个集成开发环境,其中包含了Windows SDK所有工具和定义;所以安装了VC后就不用特意安装SDK了。

五、正文1、实验程序的结构图(流程图);开始Wait ProductsWait BufferConsumeProduceWhile consumeWhile produce结束2、数据结构及信号量定义的说明;(1) CreateThread●功能——创建一个在调用进程的地址空间中执行的线程●格式HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParamiter,DWORD dwCreationFlags,Lpdword lpThread );●参数说明lpThreadAttributes——指向一个LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。

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

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

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

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

lpThread——保存线程标志符(32位)(2) CreateMutex●功能——创建一个命名或匿名的互斥量对象●格式HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner,LPCTSTR lpName);●参数说明lpMutexAttributes——必须取值NULL。

bInitialOwner——指示当前线程是否马上拥有该互斥量(即马上加锁)。

lpName——互斥量名称。

(3) CreateSemaphore●功能——创建一个命名或匿名的信号量对象●格式HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCTSTR lpName );●参数说明lpSemaphoreAttributes——必须取值NULL。

lInitialCount——信号量的初始值。

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

lMaximumCount——信号量的最大值。

lpName——信号量名称。

(4) WaitForSingleObject●功能——使程序处于等待状态,直到信号量hHandle出现(即其值大于等于1)或超过规定的等待时间DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);●参数说明hHandle——信号量指针。

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

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

成功执行则返回非0值●格式BOOL ReleaseSemaphore(HANDLE hSemaphore,LONG lReleaseCount,LPLONG lppreviousCount );●参数说明hSemaphore——信号量指针。

lReleaseCount——信号量的增量。

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

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

成功调用则返回0●格式BOOL ReleaseMutex(HANDLE hMutex);●参数说明hMutex——互斥量指针。

(7) InitializeCriticalSection●功能——初始化临界区对象●格式VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);●参数说明lpCriticalSection——指向临界区对象的指针。

(8) EnterCriticalSection●功能——等待指定临界区对象的所有权VOID enterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);●参数说明lpCriticalSection——指向临界区对象的指针。

(9) LeaveCriticalSection●功能——释放指定临界区对象的所有权●格式VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);●参数说明lpCriticalSection——指向临界区对象的指针。

3、实验的步骤;(1) 打开VC,选择菜单项file->new,选择projects选项卡并建立一个名为" R_WP1"的win32 console applicatoin工程;创建时注意指定创建该工程的目录;(2) 在工程中创建源文件" R_WP1.cpp":选择菜单项project->add to project->files,在选择框中输入自己想要创建的文件名,这里是" R_WP1.cpp";在接下来询问是否创建新文件时回答"yes";然后通过Workspace->FileView->Source Files打开该文件,在其中编辑源文件并保存.(3) 通过调用菜单命令项build->build all进行编译连接,可以在指定的工程目录下得到debug-> R_WP1.exe程序,然后把给定的test.txt文件存入该debug目录下,就可以在控制台进入该debug目录运行程序了。

需要强调的是在创建数据文件时,由于涉及到文件格式问题,最好在记事本中手工逐个输入数据,而不要拷贝粘贴数据。

4、主要算法创建生产者和消费者线程for(i =0;i< (int) n_Thread;i++){if(Thread_Info[i].entity =='P')h_Thread[i]= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(Thread_Info[i]),0,NULL);elseh_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),&(Thread_Info[i]),0,NULL);}生产者进程void Produce(void *p){//局部变量声明;DWORD wait_for_semaphore,wait_for_mutex,m_delay;int m_serial;//获得本线程的信息;m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);Sleep(m_delay);//开始请求生产printf("Producer %2d sends the produce require.\n",m_serial);//确认有空缓冲区可供生产,同时将空位置数empty减1;用于生产者和消费者的同步;wait_for_semaphore = WaitForSingleObject(empty_semaphore,-1);//互斥访问下一个可用于生产的空临界区,实现写写互斥;wait_for_mutex = WaitForSingleObject(h_mutex,-1);int ProducePos = FindProducePosition();ReleaseMutex(h_mutex);//生产者在获得自己的空位置并做上标记后,以下的写操作在生产者之间可以并发;//核心生产步骤中,程序将生产者的ID作为产品编号放入,方便消费者识别;printf("Producer %2d begin to produce at position %2d.\n",m_serial,ProducePos);Buffer_Critical[ProducePos] = m_serial;printf("Producer %2d finish producing :\n ",m_serial);printf(" position[ %2d ]:%3d \n" ,ProducePos,Buffer_Critical[ProducePos]);//使生产者写的缓冲区可以被多个消费者使用,实现读写同步;ReleaseSemaphore(h_Semaphore[m_serial],n_Thread,NULL);}消费者进程void Consume(void * p){//局部变量声明;DWORD wait_for_semaphore,m_delay;int m_serial,m_requestNum; //消费者的序列号和请求的数目;int m_thread_request[MAX_THREAD_NUM];//本消费线程的请求队列;//提取本线程的信息到本地;m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);m_requestNum = ((ThreadInfo *)(p))->n_request;for (int i = 0;i<m_requestNum;i++)m_thread_request[i] = ((ThreadInfo*)(p))->thread_request[i];Sleep(m_delay);//循环进行所需产品的消费for(i =0;i<m_requestNum;i++){//请求消费下一个产品printf("Consumer %2d request to consume %2d product\n",m_serial,m_thread_request[i]);//如果对应生产者没有生产,则等待;如果生产了,允许的消费者数目-1;实现了读写同步;wait_for_semaphore=WaitForSingleObject(h_Semaphore[m_thread_request[i]],-1);//查询所需产品放到缓冲区的号int BufferPos=FindBufferPosition(m_thread_request[i]);//开始进行具体缓冲区的消费处理,读和读在该缓冲区上仍然是互斥的;//进入临界区后执行消费动作;并在完成此次请求后,通知另外的消费者本处请求已//经满足;同时如果对应的产品使用完毕,就做相应处理;并给出相应动作的界面提//示;该相应处理指将相应缓冲区清空,并增加代表空缓冲区的信号量;EnterCriticalSection(&PC_Critical[BufferPos]);printf("Consumer%2d begin to consume %2d product \n",m_serial,m_thread_request[i]);((ThreadInfo*)(p))->thread_request[i] =-1;if(!IfInOtherRequest(m_thread_request[i])){Buffer_Critical[BufferPos] = -1; //标记缓冲区为空;printf("Consumer%2d finish consuming %2d:\n ",m_serial,m_thread_request[i]);printf(" position[ %2d ]:%3d \n" ,BufferPos,Buffer_Critical[BufferPos]);ReleaseSemaphore(empty_semaphore,1,NULL);}else{printf("Consumer %2d finish consuming product %2d\n ",m_serial,m_thread_request[i]);}//离开临界区LeaveCriticalSection(&PC_Critical[BufferPos]);}}5、实验运行图;6、实验结果分析;只有在生产者生产了产品并将产品存放到缓冲池中消费者才能去消费,当缓冲池为空时消费者不能消费六、结论(应当准确、完整、明确精练;也可以在结论或讨论中提出建议、设想、尚待解决问题等。

相关文档
最新文档