📄 producedlg.cpp
字号:
// ProduceDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Produce.h"
#include "ProduceDlg.h"
#include"afxmt.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
volatile int pa=0,pb=0,s1=0,s2=0,pt=0,ta=0,tb=0;
/*CEvent pas1(false,true,NULL,NULL);
CEvent pbs2(false,true,NULL,NULL);
CEvent s1p(false,true,NULL,NULL);
CEvent s2p(false,true,NULL,NULL);*/
CCriticalSection Producea;
CCriticalSection Produceb;
CCriticalSection Shelf1;
CCriticalSection Shelf2;
CCriticalSection Product;
CSemaphore pda(2,2);
CSemaphore pdb(2,2);
CSemaphore sh1(2,2);
CSemaphore sh2(2,2);
volatile m_bStop=false;
CWinThread *pProduceA;
CWinThread *pShelfF2;
CWinThread *pShelfF1;
CWinThread *pAssembleLine;
CWinThread *pProduceB;
//CEvent pas1(false,true,NULL,NULL);
/*CSemaphore produceA(20,20);
CSemaphore produceB(20,20);
CSemaphore shelf1(10,10);
CSemaphore shelf2(10,10);
*/
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CProduceDlg dialog
CProduceDlg::CProduceDlg(CWnd* pParent /*=NULL*/)
: CDialog(CProduceDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CProduceDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CProduceDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CProduceDlg)
DDX_Control(pDX, IDC_DEPOT, m_bProduct);
DDX_Control(pDX, IDC_B, m_bProduceB);
DDX_Control(pDX, IDC_F2, m_bShelf2);
DDX_Control(pDX, IDC_F1, m_bShelf1);
DDX_Control(pDX, IDC_A, m_bProduceA);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CProduceDlg, CDialog)
//{{AFX_MSG_MAP(CProduceDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_START, OnStart)
ON_BN_CLICKED(IDC_STOP, OnStop)
ON_BN_CLICKED(IDC_STARTASS, OnStartass)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CProduceDlg message handlers
BOOL CProduceDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
pProduceA=AfxBeginThread(ProduceA, //创建线程A
&m_bProduceA,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
pProduceB=AfxBeginThread(ProduceB, //创建线程B
&m_bProduceB,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
pShelfF1=AfxBeginThread(PutToShelfA, //创建货架F1的线程
&m_bShelf1,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
pShelfF2=AfxBeginThread(PutToShelfB, //创建货架F2的线程
&m_bShelf2,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
pAssembleLine=AfxBeginThread(AssembleLine, //创建装配线程
&m_bProduct,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
return TRUE; // return TRUE unless you set the focus to a control
}
void CProduceDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CProduceDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CProduceDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
UINT ProduceA(LPVOID pParam)//生产A的线程函数.
{
while(true)
{
if(pa<20)
{
CEdit *pEdit=(CEdit *)pParam; //转换参数类型.
WaitForSingleObject(pda.m_hObject,INFINITE);//申请生产A的资源.
Producea.Lock(1); //将生产A的资源锁定.
CString stra; //拼接配件A
for(int i=0;i<pa;i++)
stra=stra+"A ";
pEdit->SetWindowText(stra);//显示配件A.
CString str1;
str1.Format("%d",pa);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_AN,str1); //显示配件A的个数.
pa++; //A配件库里面A的剩余数量加1.
CString strta; //显示配件A的总数量.
strta.Format("%d",ta);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_TA,strta);
ta++; //配件A的总数量加1
Producea.Unlock(); //解除锁定.
ReleaseSemaphore(pda.m_hObject,1,NULL);//释放申请的资源
}
Sleep(1000); //等待一秒.
}
return 0;
}
UINT ProduceB(LPVOID pParam)//生产B的线程.
{
while(true)
{
if(pb<20)
{
CEdit *pEdit=(CEdit*)pParam;
WaitForSingleObject(pdb.m_hObject,INFINITE);//申请生产B的资源.
Produceb.Lock(1);//将生产B的资源锁定.
CString str; //生产产品B
for(int i=0;i<pb;i++)
str=str+"B ";
pEdit->SetWindowText(str);//显示产品
CString str1; //显示配件B的个数.
str1.Format("%d",pb);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_BN,str1);
pb++; //指针后移.
CString strtb; //显示配件B的总个数.
strtb.Format("%d",tb);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_TB,strtb);
tb++;
Produceb.Unlock();//解除锁定.
ReleaseSemaphore(pdb.m_hObject,1,NULL);//释放申请的资源.
}
Sleep(1000); //等待一秒.
}
return 0;
}
UINT PutToShelfA(LPVOID pParam)//将A放入货架F1上.
{
while(true)
{
if((pa>0)&&(s1<10))//若货架F1还没有放满且配件A库还有库存.
{
CEdit *pEdit=(CEdit*)pParam;
WaitForSingleObject(pda.m_hObject,INFINITE); //申请配件A的使用权.
Producea.Lock(1); //锁定配件A的仓库
pa--; //配件A的库存减1
CString stran;//更新配件库中A的数量.
stran.Format("%d",pa);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_AN,stran);
CString stra;////更新配件A.
for(int i=0;i<pa;i++)
stra=stra+"A ";
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_A,stra);
Producea.Unlock(); //解除对配件A库的锁定.
ReleaseSemaphore(pda.m_hObject,1,NULL);//释放对配件A库的使用权.
WaitForSingleObject(sh1.m_hObject,INFINITE);//申请对货架F1的使用权
Shelf1.Lock(1);//锁定货架F1
s1++;
CString str1;//在货架A上显示A
for(int j=0;j<s1;j++)
str1=str1+"A ";
pEdit->SetWindowText(str1);
CString strn1; //显示货架上A的数量.
strn1.Format("%d",s1);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_SA,strn1);
Shelf1.Unlock();//解除对货架F1的锁定.
ReleaseSemaphore(sh1.m_hObject,1,NULL);//释放对货架F1的使用权
}
Sleep(1000);
}
return 0;
}
UINT PutToShelfB(LPVOID pParam)//将B放入货架F2上.
{
while(true)
{
if((pb>0)&&(s2<10))//若货架F2还没有放满且B配件库还有配件B.
{
CEdit *pEdit=(CEdit*)pParam;
WaitForSingleObject(pdb.m_hObject,INFINITE); //申请配件B库的使用权.
WaitForSingleObject(sh2.m_hObject,INFINITE);
Produceb.Lock(1); //锁定配件B库,此操作将B从仓库中取出.
Shelf2.Lock(1); //锁定对货架F2的访问.
pb--; //配件B的库存数量减1
CString strbn;
strbn.Format("%d",pb);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_BN,strbn);//更新配件B的数量.
CString strb;
for(int i=0;i<pb;i++)
strb=strb+"B ";
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_B,strb);//更新配件B.
s2++;//货架上的配件B上数量加1.
CString str2; //显示货架上B的个数.
for(int j=0;j<s2;j++)
str2=str2+"B ";
pEdit->SetWindowText(str2);
CString strn2; //更新货架F2上的配件A的个数.
strn2.Format("%d",s2);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_SB,strn2);
Shelf2.Unlock();//释放对货架2的访问
Produceb.Unlock();//释放对配件A仓库的访问
ReleaseSemaphore(sh2.m_hObject,1,NULL);//释放对货架2进行访问的信号量
ReleaseSemaphore(pdb.m_hObject,1,NULL);//释放对仓库B进行访问的信号量.,
}
Sleep(1000);
}return 0;
}
UINT AssembleLine(LPVOID pParam) //将A与B进行组装成成品的线程.
{
while(true)
{
if((s1>0)&&(s2>0)) //若货架F1与F2上非空.
{
if(pt>=40)
{
AfxMessageBox("产品仓库已满!"); //若产品数超过了四十个.
// Sleep(5000); //等待五秒钟.
pt=pt/4; //产品数设置为原来的四分之一
}
else
{
CEdit *pEdit=(CEdit*)pParam;
WaitForSingleObject(sh1.m_hObject,INFINITE); //申请货架F1的资源.
WaitForSingleObject(sh2.m_hObject,INFINITE); //申请货架F2的资源.
Shelf1.Lock(1); //锁定货架F1.
Shelf2.Lock(1); //锁定货架F2
s1--; //货架F1上的配件A数量减1
pt++; //产品个数加1;
s2--; //货架F2上的配件B数量减1
CString str1n; //显示货架F1上配件A的个数.
str1n.Format("%d",s1);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_SA,str1n);
CString str2n; //显示货架F2上配件B.
str2n.Format("%d",s2);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_SB,str2n);
CString str1; //更新货架F1上的配件个数.
for(int i=1;i<=s1;i++)
str1+="A ";
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_F1,str1);
CString str2; //更新货架F2上的配件个数.
for(int j=1;j<=s1;j++)
str2+="B ";
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_F2,str2);
CString strp; //更新产品
for(int k=0;k<pt;k++)
{
strp+='A';
strp+='-';
strp+='B';
strp+=" ";
if(5==(k%6))
strp+="\r\n\r\n";
}
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_DEPOT,strp);
CString strpn;//更新产品个数
strpn.Format("%d",pt);
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_PN,strpn);
Shelf2.Unlock();//释放货架F2.
Shelf1.Unlock();//释放货架F1.
ReleaseSemaphore(sh2.m_hObject,1,NULL);//释放资源.
ReleaseSemaphore(sh1.m_hObject,1,NULL);//释放资源.
}
}
Sleep(1500);
}
return 0;
}
void CProduceDlg::OnStart()
{
// TODO: Add your control notification handler code here
pProduceA->ResumeThread();//启动生产A的线程.
pProduceB->ResumeThread();//启动生产B的线程.
pShelfF1->ResumeThread(); //启动将A放到货架F1上的线程
pShelfF2->ResumeThread();//启动将B放到货架F2上的线程.
pAssembleLine->ResumeThread(); //启动装配A与B的线程.
}
void CProduceDlg::OnStop()
{
// TODO: Add your control notification handler code here
pProduceA->SuspendThread();
pShelfF2->SuspendThread();
pShelfF1->SuspendThread();
pAssembleLine->SuspendThread();
pProduceB->SuspendThread();
}
void CProduceDlg::OnStartass()
{
// TODO: Add your control notification handler code here
pProduceA->SuspendThread();
pShelfF2->SuspendThread();
pShelfF1->SuspendThread();
pProduceB->SuspendThread();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -