生产者消费者模拟Word格式文档下载.docx

上传人:b****4 文档编号:6550828 上传时间:2023-05-06 格式:DOCX 页数:24 大小:303.51KB
下载 相关 举报
生产者消费者模拟Word格式文档下载.docx_第1页
第1页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第2页
第2页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第3页
第3页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第4页
第4页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第5页
第5页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第6页
第6页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第7页
第7页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第8页
第8页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第9页
第9页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第10页
第10页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第11页
第11页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第12页
第12页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第13页
第13页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第14页
第14页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第15页
第15页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第16页
第16页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第17页
第17页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第18页
第18页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第19页
第19页 / 共24页
生产者消费者模拟Word格式文档下载.docx_第20页
第20页 / 共24页
亲,该文档总共24页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

生产者消费者模拟Word格式文档下载.docx

《生产者消费者模拟Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《生产者消费者模拟Word格式文档下载.docx(24页珍藏版)》请在冰点文库上搜索。

生产者消费者模拟Word格式文档下载.docx

3)生产者的生产速度与消费者的消费速度均可在程序界面调节

4)多个生产者或多个消费者之间必须有共享对缓冲区进行操作的函数代码

5)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、

当前生产者与消费者的指针位置,以及生产者和消费者线程标识符

三、系统分析与设计

1、系统分析:

在学习进程互斥中,生产者-消费者问题是一个经典的,具有代表性的进程同步问题。

一个有限缓冲池和两类线程,它们是生产者和消费者,生产者把产品放入缓冲区,相反消费者便是从缓冲区中拿走产品。

两个线程对同一有限缓冲区的互斥访问是该问题有很大的代表性以及使用价值的根本原因。

该问题可以用三种方法实现,第一种是利用记录型信号量机制解决,第二种是利用AND信号量机制解决,第三种是利用管程机制解决。

本程序使用第一种方式实现。

假定在生产者和消费者之间有一个大小为100的缓冲区,这时可利用互斥信号量wait来实现诸进程对缓冲池的互斥使用。

利用信号量empty表示缓冲区中空缓冲区的数量。

对缓冲池的访问有如下规则:

只用缓冲区未满,生产者便可对其进行访问,但只能有一个生产者进行访问,其他不能进行访问;

只要缓冲区未空,消费者便可对其进行消费取走商品,且可以有多个消费者同时进行消费。

生产者在缓冲区满时必须等待,直到缓冲区有空间才继续生产。

同时当有另一生产者进行对缓冲池访问时也必须等待。

消费者在缓冲区空时必须等待,直到缓冲区中有产品才能继续消费。

2、系统设计:

程序的整个过程如下图所示,主界面时可以选择不同的登录界面,在选择生产者登录界

面时,根据不同的需要进行修改。

在登录消费者界面时,也可以根据不同的选择进行更改变量,同时进行数据的更新。

3、模块设计:

系统界面分为生产者界面和消费者界面,不同界面为不同用户使用。

以下是不同用户的使用设计。

各程序模块之间的调用关系如下图所示:

(1)信号量初始化模块

生产者消费者中使用了两个同步信号量和一个互斥信号量定义了。

同步信号量empty_sem初值为20,sem_init(&

empty_sem,0,20),full_sem初值为0,sem_init(&

full_sem,0,0),用默认属性初始化一个互斥锁对象pthread_mutex_init(&

mutex,NULL)。

(2)生产者线程模块

使用变量countp进行while循环的控制,当countp<

20时进入while循环。

在循环中判断同步信号量empty_sem和互斥信号量mutex,使用语句sem_wait(&

empty_sem),pthread_mutex_lock(&

mutex)。

然后生产数据,放入缓冲区中。

用指针in控制放入缓冲区的位置,用countp++进行循环的控制。

(3)消费者线程模块

使用变量countc进行while循环的控制,当countc<

在循环中判断同步信号量full_sem和互斥信号量mutex,使用语句sem_wait(&

full_sem),pthread_mutex_lock(&

然后消费数据,从缓冲区中取出。

用指针out控制取走缓冲区的位置,用countc++进行循环的控制。

(4)主函数模块

定义了三个消费者线程和三个生产者线程。

调用信号量初始化函数。

使用函数pthread_create用来创建线程,以及用函数pthread_join用来等待一个线程的结束

4、数据结构说明:

intm_Time;

//执行间隔HANDLEm_Thread;

//线程句柄HANDLEm_hStopEvent;

//退出线程事件StoreHouse*m_pHouse;

//货仓指针CCustomerDlg*m_pDialog;

//对话框指针voidSetHouse(StoreHouse*pHouse){m_pHouse=pHouse;

}//设置仓库voidSetDialog(CCustomerDlg*pDlg){m_pDialog=pDlg;

}//设置对话框virtualvoidDo()=0;

//执行操作virtualvoidStart(intspeed);

//开始运行

virtualvoidStop();

//结束运行intm_nCurrentSize;

//当时仓储量intm_nMaxSize;

//最大仓储量REFRESH_FUNCm_RefreshFunc;

//刷新回调函数void*m_pParam;

//回调函数的参数CRITICAL_SECTIONm_csLock;

//本实例锁HANDLEm_hEventGoods;

//此事件置信则表示仓库有货HANDLEm_hEventHouse;

//此事件置信则标识仓库有空位HANDLEm_hStopEvents;

//仓库倒塌,所有工作者线程停止运行voidSetMaxSize(intnMaxSize=DEFAULT_SIZE);

//设置最大仓储量intGetMaxSize(void);

//得到最大尺寸intGetCurrentSize(void);

//得到当时仓储量voidCheckStore(void);

//检查仓库

5、算法流程图:

四、模块调试与系统测试

1、模块调试

●输入形式和输入值的范围

生产消费速度输入值的范围为1~20之间。

●输出形式

(1)生产者:

在相应位置显示所生产的产品名称以及数量

(2)消费者:

在相应的位置显示消费情况

●程序所能达到的功能

模拟仿真“生产者-消费者”问题的解决过程及方法。

当生产者生产进入生产状态时,其他生产者就不能进行生产和访问缓冲池,而消费者则可以进行访问,并进行消费产品。

测试名称

测试目的

验证系统的合理性

测试技术

数据测试

测试方法

黑盒测试

测试内容

测试程序的正确性

测试步骤

输入生产消费速度,启动仓库,增加生产者消费者的数目

测试数据

生产者速度1,消费者速度1

预期结果

能正常运行

测试结果

正常运行

2、系统测试

3、调试分析:

1、使用时间控件是为了防止界面刷新太快而被锁死,无法点击,默认500毫秒刷新一下工作者产生的信息,下面是关键代码。

voidCCustomerDlg:

:

OnTimer(UINTnIDEvent)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

if(nIDEvent==MESSAGE_TIMER)

{

inti;

CStringszOldMessage;

CStringszMessage;

GetDlgItem(IDC_EDIT_MESSAGE)->

GetWindowText(szOldMessage);

EnterCriticalSection(&

m_csMessages_Lock);

if(m_Messages.GetSize()<

=0)

{

LeaveCriticalSection(&

return;

}

for(i=0;

i<

m_Messages.GetSize();

i++)

szMessage=m_Messages.ElementAt(i);

szOldMessage=szOldMessage+szMessage;

m_Messages.RemoveAll();

LeaveCriticalSection(&

SetWindowText(szOldMessage);

((CEdit*)GetDlgItem(IDC_EDIT_MESSAGE))->

LineScroll(10000);

}

CDialog:

OnTimer(nIDEvent);

}

五、用户手册

1.本程序是在MicrosoftWindowsXPSP3环境下编写的,运行平台可为Windows95/98/Windows2000/WindowsXP/Windowsvista/Windows7。

2.本程序是可视化的界面,可以直接运行可执行文件。

3.运行程序后,分别输入生产消费的速度,注意输入的时候为1-20之间的任意数字,然后启动仓库就可以了,在运行的过程中可以随时更改生产者消费者的数量。

4.程序的主界面如下:

六、程序清单

//CAboutDlgdialogusedforAppAbout

classCAboutDlg:

publicCDialog

public:

CAboutDlg();

//DialogData

//{{AFX_DATA(CAboutDlg)

enum{IDD=IDD_ABOUTBOX};

//}}AFX_DATA

//ClassWizardgeneratedvirtualfunctionoverrides

//{{AFX_VIRTUAL(CAboutDlg)

protected:

virtualvoidDoDataExchange(CDataExchange*pDX);

//DDX/DDVsupport

//}}AFX_VIRTUAL

//Implementation

protected:

//{{AFX_MSG(CAboutDlg)

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

CAboutDlg:

CAboutDlg():

CDialog(CAboutDlg:

IDD)

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

voidCAboutDlg:

DoDataExchange(CDataExchange*pDX)

DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

//Nomessagehandlers

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

//CCustomerDlgdialog

CCustomerDlg:

CCustomerDlg(CWnd*pParent/*=NULL*/)

:

CDialog(CCustomerDlg:

IDD,pParent)

//{{AFX_DATA_INIT(CCustomerDlg)

m_ps=0;

m_cs=0;

m_hIcon=AfxGetApp()->

LoadIcon(IDR_MAINFRAME);

m_pHouse=NULL;

m_nProductors=0;

m_nConsumers=0;

InitializeCriticalSection(&

~CCustomerDlg()

DeleteCriticalSection(&

//{{AFX_DATA_MAP(CCustomerDlg)

DDX_Control(pDX,IDC_PROGRESS_STORE,m_StoreNums);

DDX_Text(pDX,IDC_EDIT_PS,m_ps);

DDV_MinMaxInt(pDX,m_ps,1,20);

DDX_Text(pDX,IDC_EDIT_CS,m_cs);

DDV_MinMaxInt(pDX,m_cs,1,20);

BEGIN_MESSAGE_MAP(CCustomerDlg,CDialog)

//{{AFX_MSG_MAP(CCustomerDlg)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_BN_CLICKED(IDC_BUTTON_START,OnButtonStart)

ON_BN_CLICKED(IDC_BUTTON_STOP,OnButtonStop)

ON_BN_CLICKED(IDC_BUTTON_ADDP,OnButtonAddp)

ON_BN_CLICKED(IDC_BUTTON_ADDC,OnButtonAddc)

ON_WM_CLOSE()

ON_WM_TIMER()

//CCustomerDlgmessagehandlers

BOOLCCustomerDlg:

OnInitDialog()

OnInitDialog();

//Add"

About..."

menuitemtosystemmenu.

//IDM_ABOUTBOXmustbeinthesystemcommandrange.

ASSERT((IDM_ABOUTBOX&

0xFFF0)==IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX<

0xF000);

CMenu*pSysMenu=GetSystemMenu(FALSE);

if(pSysMenu!

=NULL)

CStringstrAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if(!

strAboutMenu.IsEmpty())

pSysMenu->

AppendMenu(MF_SEPARATOR);

AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);

SetIcon(m_hIcon,TRUE);

//Setbigicon

SetIcon(m_hIcon,FALSE);

//Setsmallicon

Addextrainitializationhere

GetDlgItem(IDC_BUTTON_START)->

EnableWindow(TRUE);

GetDlgItem(IDC_BUTTON_STOP)->

EnableWindow(FALSE);

GetDlgItem(IDC_BUTTON_ADDC)->

GetDlgItem(IDC_BUTTON_ADDP)->

SetTimer(MESSAGE_TIMER,TIMER_INVAL,NULL);

returnTRUE;

//returnTRUEunlessyousetthefocustoacontrol

theframework.

OnPaint()

if(IsIconic())

CPaintDCdc(this);

//devicecontextforpainting

SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);

//Centericoninclientrectangle

intcxIcon=GetSystemMetrics(SM_CXICON);

intcyIcon=GetSystemMetrics(SM_CYICON);

CRectrect;

GetClientRect(&

rect);

intx=(rect.Width()-cxIcon+1)/2;

inty=(rect.Height()-cyIcon+1)/2;

//Drawtheicon

dc.DrawIcon(x,y,m_hIcon);

else

//CDialog:

OnPaint();

CRectrect;

GetClientRect(&

CDCdcMem;

dcMem.CreateCompatibleDC(&

dc);

CBitmapbmpBackground;

bmpBackground.LoadBitmap(IDB_BITMAP1);

//IDB_BITMAP是你自己的图对应的ID,由于我刚刚加入的位图资源

//被我命名成了IDB_Bg,因而我这句就是bmpBackground.LoadBitmap(IDB_Bg);

BITMAPbitmap;

bmpBackground.GetBitmap(&

bitmap);

CBitmap*pbmpOld=dcMem.SelectObject(&

bmpBackground);

dc.StretchBlt(0,0,rect.Width(),rect.Height(),&

dcMem,0,0,

bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);

HCURSORCCustomerDlg:

OnQueryDragIcon()

return(HCURSOR)m_hIcon;

Refresh(void*pParam,StoreHouse*pHouse)

if(pParam==NULL

||pHouse==NULL)

return;

CCustomerDlg*pThis=(CCustomerDlg*)pParam;

chartempBuffer[BUFF_SIZE64];

_snprintf(tempBuffer,BUFF_SIZE64,"

%d"

pHouse->

GetCurrentSize());

pThis->

GetDlgItem(IDC_STATIC_CURRENT)->

SetWindowText(tempBuffer);

m_StoreNums.SetPos(pHouse->

ShowMessage(constchar*pMessage)

CStringszMessage;

szMessage.Format("

%s%c%c"

pMessage,13,10);

EnterCriticalSection(&

m_Messages.Add(szMessage);

LeaveCriticalSection(&

OnButtonStart()

Addyourcontrolnotificationhandlercodehere

if(m_pHouse!

m_pHouse=newStoreHouse;

m_pHouse->

SetRefresh(Refresh,this);

m_StoreNums.SetRange(0,m_pHouse->

GetMaxSize());

UpdateData(TRUE);

//获取速度

TRACE("

%d,%d"

m_cs,m_ps);

m_pHouse->

GetDlgItem(IDC_STATIC_MAX)->

GetDlgItem(IDC_STATIC_CURRENT)->

SetWindowText("

0"

);

GetD

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2