操作系统课程设计——生产者消费者问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机与信息学院
《操作系统与编译原理联合课程设计报告》
专题:操作系统部分
学生姓名:
学号:
专业班级:
指导教师:
2014 年 7 月
一、设计目标
多进程/线程编程:生产者-消费者问题。设置两类进程/线程,一类为生产者,一类为消费者;建立缓冲区的数据结构;随机启动生产者或消费者;显示缓冲区状况;随着进程/线程每次操作缓冲区,更新显示。
二、设计思路
1.开发平台:Visual C++6.0
2.设计思路:
若干个生产者和若干个消费者共享一个有界缓冲区,生产者生产产品,消费者消费产品。消费者进程与生产者进程随机切换。生产者将产品生产出来后,存放到缓冲区中的空闲位置并将此缓冲区的标识置为满,若此时无空缓冲区,则进行等待。消费者将标识为满的缓冲区中的产品取出,进行消费并将该缓冲区的标志位置为空,若此时无满的缓冲区,则进行等待。
由于消费者与生产者共享缓冲区资源,且缓冲区资源属于互斥资源,所以生产者和消费者需要按照一定的规则访问缓冲区,访问规则如下:
(1)当一个消费者访问缓冲区时其他消费者不允许访问缓冲区,同样的,当一个生产者访问缓冲区时其他生产者也不能访问缓冲区。
(2)当消费者访问缓冲区资源时生产者不能访问,反之,当生产者访问缓冲区资源时消费者不能访问。
(3)当缓冲区中无产品时,消费者不能访问;当缓冲区已满时,生产者不能访问缓冲区。
生产者与消费者问题伪代码如下:
VAR mutex, empty, full: semaphore := 1, n, 0 ;
in,out: integer := 0, 0 ;
Buffer: array [0..n-1] of item ;
Parbegin
Producer:
begin
repeat
produce an item in nextp;
wait(empty);
wait(mutex);
Buffer(in) := nextp;
in := (in + 1) mod n;
signal(mutex);
signal(full);
until false
end
Consumer:
begin
repeat
wait(full);
wait(mutex);
nextc = Buffer(out);
out := (out + 1) mod n;
signal(mutex);
signal(empty);
consume the item nextc;
until false
end
Parend
程序框架如下图所示:
本程序在具体实现方面与MFC结合,将生产者-消费者问题的具体过程动态展示了出来。以下为界面的设计:
(1)界面拥有三个可输入的编辑框,分别对应着生产者数量、消费者数量以及缓冲区
大小。
(2)界面中有两个按钮,分别为“开始”和“停止”。“开始”按钮用于获取生产值数量、消费者数量以及缓冲区大小,用于初始化以上三个量,并启动进程。“停止”按钮用于停止程序的运行。
(3)三个只读的编辑框,用于动态显示消费者与生产者问题的详细过程。
MFC界面设计如下图所示:
三、核心代码
本程序的特色在于将生产者-消费者问题的内部的进程调度的细节以及缓冲区的状态变化动态的呈现在MFC的界面上。且程序中还实现了随机调度生产者进程和消费者进程。以下主要介绍随机算法以及生产者进程动态描述的源代码。消费者的代码,与生产者代码相似。
1.随机启动进程函数:
调用c++函数库中定义产生随机数的函数,生成整数随机数。使用取模的方法判断,若为奇数则创建并启动生产者进程;反之则创建并启动消费者进程。
srand(time(NULL));
for(i=0, j=0;i if (i>=CWork::producer_tcount){ CThreads[j]= ::CreateThread(NULL,0,CWork::consumer,this,0,&consumerID[j ]); ::CloseHandle(CThreads[j]); j++; } else if (j>=CWork::consumer_tcount){ PThreads[i]=::CreateThread(NULL,0,CWork::producer,this,0,&producerID[i] ); ::CloseHandle(PThreads[i]); i++; } else{ int n = rand()%2; if (n == 0){ PThreads[i]=CreateThread(NULL,0,CWork::producer,this,0,&producerID[ i]); ::CloseHandle(PThreads[i]); i++; } else{ CThreads[j]=CreateThread(NULL,0,CWork::consumer,this,0,&consumerID[ j]); ::CloseHandle(CThreads[j]); j++; } } } 2.生产函数: 实现生产者生产产品的过程,即将空闲缓冲区位置更改为满的缓冲区位置。 void CWork::produce(CMy20112880P_CDlg* pDlg){ CString str1,str2,str3; str1="生产"; pDlg->SetDlgItemText(IDC_ONE,str1); pDlg->SetDlgItemInt(IDC_TWO,product_num); buffer[in]=product_num; product_num++; buffer_state[in]='@'; show_p(pDlg); in=(in+1)%size; ::Sleep(1000); } 3.生产者生产状态显示函数: 实现显示生产者生产产品后,动态显示相关信息。 void CWork::show_p(CMy20112880P_CDlg* pDlg) { CString result; CString str2 (": " );