操作系统之生产者消费者问题(c++实现)

更新时间:2024-05-01 05:22:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

操作系统

课程设计报告

专业 计算机科学与技术

丁可 B计123班 1210704314 李先锋 2015年11月20日

学生姓名 班学

级 号

指导教师 完成日期

信息工程学院

题目:生产者-消费者问题的模拟实现

一、设计目的

本课程设计是学习完“操作系统原理”课程后进行的一次全面的综合训练,通过课程设计,更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强学生的动手能力。

二、设计内容

1、概述

用进程同步方法解决“生产者-消费者”问题,C或C++语言实现。 1、设计目的

通过研究进程并发和信号量机制,实现生产者-消费者问题的并发控制。 2、设计要求

1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者进程的标识符。

说明:有界缓冲区(提示:有界缓冲区可用数组实现)内设有20个存储单元,放入/取出的数据项设定为1-20这20个整型数。

2)生产者和消费者各有两个以上。

3)多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码。 2、设计原理

在同一个进程地址空间内执行的两个线程生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。 3、详细设计及编码 定义两个信号量

HANDLE g_hFullSemaphore;//资源信号量:缓冲区满

HANDLE g_hEmptySemaphore;//资源信号量:缓冲区空 unsigned short in = 0;//用于记录生产者的指针位置 unsigned short out = 0;//用于记录消费者的指针位置 HANDLE g_hMutex;//线程间的互斥信号量

生产者进程 while(TRUE){

生产一个产品;

P(g_hEmptySemaphore); P(mutex1);

产品送往buffer(in); in=(in+1)mod n; V(mutex1);

V(g_hFullSemaphore); } 消费者进程 while(TRUE){

P(g_hFullSemaphore); P(mutex2);

从buffer(out)中取出产品; out=(out+1)mod n; V(mutex2);

V(g_hEmptySemaphore);

(算法流程图、编程及程序注释等) 主要的方法:

4、运行结果分析 1、运行示例

在 c++中运行源程序 ,程序主界面截图.按回车及申请资源和缓冲区进行 p 操作和申请互斥(生产者和消费者都是2个)

(运行界面截图、界面说明、输入输出数据说明和分析等) 附录代码:

#include #include

const unsigned short SIZE_OF_BUFFER = 20;//有界缓冲区长度

int g_buffer[SIZE_OF_BUFFER];//开辟缓冲区?用数组表示?可以看成是一个循环队列 unsigned short ProductID = 0;//新生产出来的产品的产品号 unsigned short ConsumeID = 0;//被消耗的产品的产品号

unsigned short in = 0;//产品进缓冲区时的缓冲区下标?用于记录生产者的指针位置 unsigned short out = 0;//产品出缓冲区时的缓冲区下标?用于记录消费者的指针位置 bool g_continue = 1;//控制程序运行:1 表示继续运行?0 表示停止运行 HANDLE g_hMutex;//线程间的互斥信号量

HANDLE g_hFullSemaphore;//资源信号量:缓冲区满 HANDLE g_hEmptySemaphore;//资源信号量:缓冲区空 DWORD WINAPI Producer(LPVOID);//生产者线程 DWORD WINAPI Consumer(LPVOID);//消费者线程

const unsigned short PRODUCERS_COUNT=2;//生产者的个数

const unsigned short CONSUMERS_COUNT=2;//消费者的个数 const unsigned short

THREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT;//总线程数

HANDLE hThreads[PRODUCERS_COUNT];//各线程的 handle DWORD producerID[CONSUMERS_COUNT];//生产者线程的标识符 DWORD consumerID[THREADS_COUNT];//消费者线程的标识符 /*----------------------------程序提示信息开始------------------------------*/ void info()//程序提示信息 {

std::cout<<\

std::cout<<\课程设计课题 : 生产者-消费者问题的模拟实现 |\std::cout<<\指 导 老 师 : 李先锋 |\std::cout<<\学 生 : 丁可 |\std::cout<<\班 级 : B计123班 |\std::cout<<\std::cout<<\》按回车开始该程序 \getchar(); }

/*----------------------------程序提示信息结束------------------------------*/ /*----------------------------生产一个产品开始------------------------------*/ //生产一个产品:输出其 ID 号 void Produce() {

std::cout<

std::cerr<<\生产一个产品: \std::cout<

/*----------------------------生产一个产品结束------------------------------*/ /*----------------------把新生产的产品放入缓冲区开------------------------*/ //把新生产的产品放入缓冲区 void Append() {

std::cerr<<\把生产的产品送入缓冲区\g_buffer[in]=ProductID;

in=(in+1)%SIZE_OF_BUFFER; std::cerr<

std::cout<<\缓冲区 产品 生产者/消费者\//新产品放入缓冲区后?输出缓冲区当前的状态 for(int i=0;i

//输出缓冲区下标 if (i<10)

std::cout<

std::cout<

{

if(g_buffer[i]<10) std::cout<<\else

std::cout<<\

std::cout<<\生产者\输出生产者的指针位置 }

if(i==out) {

if(g_buffer[i]<10) std::cout<<\else

std::cout<<\

std::cout<<\消费者\输出消费者的指针位置 }

std::cout<

/*----------------------把新生产的产品放入缓冲区结------------------------*/ /*----------------------------消费一个产品开始------------------------------*/ void Consume()//消费一个产品 {

std::cout<

std::cerr<<\消费一个产品: \std::cout<

/*----------------------------消费一个产品结束------------------------------*/ /*-----------------------从缓冲区中取出一个产品开始-------------------------*/ //从缓冲区中取出一个产品 void Take() {

std::cout<

std::cerr<<\从缓冲区取出一个产品\ConsumeID=g_buffer[out];

out=(out+1)%SIZE_OF_BUFFER; std::cerr<

std::cout<<\缓冲区 产品 生产者/消费者\//取出一个产品后:输出缓冲区当前的状态 for(int i=0;i

//输出缓冲区下标 if(i<10)

std::cout<

std::cout<

if(i==in) {

if(g_buffer[i]<10) std::cout<<\else

std::cout<<\

std::cout<<\生产者\输出生产者的指针位置 }

if(i==out) {

if(g_buffer[i]<10) std::cout<<\else

std::cout<<\

std::cout<<\消费者\输出消费者的指针位置 }

std::cout<

/*-----------------------从缓冲区中取出一个产品结束-------------------------*/ /*-----------------------------生产者线程开始-------------------------------*/

//生产者线程

DWORD WINAPI Producer(LPVOID lpPara) {

while(g_continue) {

//资源信号量的 P 操作

WaitForSingleObject(g_hFullSemaphore,INFINITE); //互斥信号量的 P 操作

WaitForSingleObject(g_hMutex,INFINITE); //生产一个产品 Produce();

//把新生产的产品放入缓冲区 Append(); Sleep(2000);

//互斥信号量的 V 操作 ReleaseMutex(g_hMutex); //资源信号量的 V 操作

ReleaseSemaphore(g_hEmptySemaphore,1,NULL); }

return 0; }

/*-----------------------------生产者线程结束-------------------------------*/ /*-----------------------------消费者线程开始-------------------------------*/ //消费者线程

DWORD WINAPI Consumer(LPVOID lpPara) {

while(g_continue) {

//资源信号量的 P 操作

WaitForSingleObject(g_hEmptySemaphore,INFINITE); //互斥信号量的 P 操作

WaitForSingleObject(g_hMutex,INFINITE); //从缓冲区中取出一个产品

Take();

//消费一个产品 Consume(); Sleep(2000);

//互斥信号量的 V 操作 ReleaseMutex(g_hMutex); //资源信号量的 V 操作

ReleaseSemaphore(g_hFullSemaphore,1,NULL); }

return 0; }

/*-----------------------------消费者线程结束-------------------------------*/ /*---------------------------创建生产者线程开始-----------------------------*/ void createPT()//创建生产者线程 {

for(int i=0;i

hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]); if(hThreads[i]==NULL) g_continue=0; } }

/*---------------------------创建生产者线程结束-----------------------------*/ /*---------------------------创建消费者线程开始-----------------------------*/

void createCT()//创建消费者线程 {

for (int j=0;j

hThreads[PRODUCERS_COUNT+j]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[j]);

if (hThreads[j]==NULL)

g_continue=0; } }

/*---------------------------创建消费者线程结束-----------------------------*/

/*-------------------------------主函数开始---------------------------------*/ int main() {

//显示程序提示信息 info();

//创建互斥信号量

g_hMutex=CreateMutex(NULL,FALSE,NULL); //创建资源信号量

g_hFullSemaphore=CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL);

g_hEmptySemaphore=CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL); //创建生产者线程 createPT();

//创建消费者线程 createCT();

//不按回车键的话程序会一直运行下去 while(g_continue) //按回车键终止程序 if(getchar())

g_continue = 0; return g_continue; }

5、设计小结

(本设计的特色、经验教训和体会等)

6、参考文献

(参考的书籍等,列出书名、作者、出版社及出版时间等,例如:

[1]计算机操作系统(第3版),汤小丹,西安电子科技大学出版社,2007年7月 [2]C语言程序设计,孟庆昌,人民邮电出版社,2006年4月

报告各部分内容根据设计的具体情况自行扩展。

本文来源:https://www.bwwdw.com/article/0qqg.html

Top