⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listdialog.cpp

📁 银行家算法:实现了动态的进程分配资源
💻 CPP
字号:
// ListDialog.cpp : implementation file
//

#include "stdafx.h"
#include "Banker.h"
#include "ListDialog.h"
#include "RsDialog.h"


// ListDialog dialog

IMPLEMENT_DYNAMIC(ListDialog, CDialog)

ListDialog::ListDialog(CWnd* pParent /*=NULL*/,UINT p,UINT r)
	: CDialog(ListDialog::IDD, pParent)
	, nP(p)
	, nR(r)
	, SafeSequence(_T(""))
	, safety(_T(""))
	, nRelease(0)
{
	Available = new UINT[nR];
	Allocation = new UINT*[nP];
	for(UINT i=0; i<nP; i++)
		Allocation[i] = new UINT[nR];
	MAX = new UINT*[nP];
	for(UINT i=0; i<nP; i++)
		MAX[i] = new UINT[nR];
	Need = new UINT*[nP];
	for(UINT i=0; i<nP; i++)
		Need[i] = new UINT[nR];
	Request = new UINT[nR];
	Work = new UINT[nR];
	Path = new UINT[nP];
	Release = new bool[nP];

	for(UINT i=0; i<nP; i++)
	  Release[i] = false;

}

ListDialog::~ListDialog()
{
	delete []Available;
	for(UINT i=0; i<nP; i++)
		delete []Allocation[i];
	delete []Allocation;

	for(UINT i=0; i<nP; i++)
		delete []MAX[i];
    delete []MAX;

	for(UINT i=0; i<nP; i++)
		delete []Need[i];
	delete []Need;

	delete []Request;
	delete []Work;
	delete []Path;
	delete []Release;

}

void ListDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, listCtrl);
	DDX_Text(pDX, IDC_SAFE, SafeSequence);
	DDX_Text(pDX, IDC_EDIT1, safety);
}


BEGIN_MESSAGE_MAP(ListDialog, CDialog)
	ON_BN_CLICKED(IDOK, &ListDialog::OnBnClickedOk)
	ON_BN_CLICKED(IDC_BUTTON2, &ListDialog::OnBnClickedButton2)
	ON_NOTIFY(NM_CLICK, IDC_LIST1, &ListDialog::OnNMClickList1)
	ON_BN_CLICKED(IDC_NEW, &ListDialog::OnBnClickedNew)
END_MESSAGE_MAP()


// ListDialog message handlers

void ListDialog::OnBnClickedOk()
{
	// TODO: Add your control notification handler code here
	OnOK();
}

BOOL ListDialog::OnInitDialog()
{
	  CDialog::OnInitDialog();

	  LONG lStyle;
      lStyle = GetWindowLongW(listCtrl.m_hWnd, GWL_STYLE);//获取当前窗口style
      lStyle &= ~LVS_TYPEMASK; //清除显示方式位
      lStyle |= LVS_REPORT; //设置style
      SetWindowLong(listCtrl.m_hWnd, GWL_STYLE, lStyle);//设置style
 
      DWORD dwStyle = listCtrl.GetExtendedStyle();
      dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
      dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
      dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
      listCtrl.SetExtendedStyle(dwStyle); //设置扩展风格
	  listCtrl.SetBkColor(RGB(180,150,240));
	  listCtrl.SetTextBkColor(RGB(180,150,240));


	  listCtrl.InsertColumn(0,_T("资 源 ---->"), LVCFMT_LEFT, 70 );//插入列
	  CString str;
	  for(UINT i=0; i<nR; i++)
	  {
		  str.Format("R%d",i);
		  listCtrl.InsertColumn( i+1,str, LVCFMT_LEFT, 30);//插入列
	  }

	  str.Format("初始总量");
	  listCtrl.InsertItem(0,str);
	  for(UINT i=0; i<nR; i++)
	  {
		  str.Format("%d",this->Available[i]);
		  listCtrl.SetItemText(0,i+1,str);
	  }
	  str.Format("可  用  量");
	  listCtrl.InsertItem(1,str);
	  for(UINT i=0; i<nR; i++)
	  {
		  str.Format("%d",this->Available[i]);
		  listCtrl.SetItemText(1,i+1,str);
	  }

	  for(UINT i=1; i<=nP; i++)
	  {
		  str.Format("P%d  已  占",i-1);
		  listCtrl.InsertItem(i*2,str);
		  for(UINT j=1; j<=nR; j++)
		  {
			  str.Format("%d",this->Allocation[i-1][j-1]);
			  listCtrl.SetItemText(i*2,j,str);
		  }
		  str.Format("P%d  总  需",i-1);
		  listCtrl.InsertItem(i*2+1,str);
		  for(UINT j=1; j<=nR; j++)
		  {
			  str.Format("%d",this->MAX[i-1][j-1]);
			  listCtrl.SetItemText(i*2+1,j,str);
		  }
	  }
	  return true;
}

bool ListDialog::Safe()
{
	int flag;
	int l = 0;
	int* finish = new int[nP];
	for(UINT i=0; i<nP; i++)
		finish[i] = 0;

	for (int i=0; i<(int)nP;i++)
		{
			if (finish[i]==0 && !Release[i])
			{
				flag = 0;
				for (UINT j=0; j<nR; j++)
				{
					if (Work[j]>=Need[i][j])
						flag += 1;
				}
		
				if(flag==nR)
				{
					Path[l]=i; 
					finish[i]=1;
					for (UINT j=0; j<nR;j++)
						Work[j] += Allocation[i][j];
					l++;
					i = -1;//!!!!!!!!!!!!!!!!!!!
				}
			}
		}
	
		delete []finish;
	return (l==nP-nRelease);
	// TODO: Add your control notification handler code here
}

void ListDialog::OnBnClickedButton2()
{
	AfxMessageBox(_T("在列表框中单击左键选中一进程,即可为其分配更多资源!"));
	// TODO: Add your control notification handler code here
}

void ListDialog::Allot()
{
	POSITION pos = listCtrl.GetFirstSelectedItemPosition();
	if (pos == NULL)
	{
		AfxMessageBox(_T("No items were selected!"));
		return;
	}
	int nItem = listCtrl.GetNextSelectedItem(pos);
	if(nItem<2)
	{
		AfxMessageBox(_T("The item selected is not a process!"));
		return;
	}

	int record = nItem;
	nItem /= 2;
	nItem -= 1;
	if(Release[nItem])
	{
		AfxMessageBox(_T("The process selected has been executed!"));
		return;
	}
	CString hint = _T("");
	hint.Format("请为P%d增添更多资源!",nItem);
	RsDialog* rd = new RsDialog(NULL,nP,nR,hint);
	do
	{
		if(rd->DoModal()==IDOK && rd->boolean)
			for(UINT i=0; i<nR; i++)
					Request[i] = rd->Data[i];
		else
			return;
	}while(!rd->boolean);

	for (UINT j=0; j<nR; j++)
		{
			if (Request[j] > Need[nItem][j])
			{
				hint.Format("出错!资源%d申请量(%d)大于剩余需要量(%d)!",j,Request[j],Need[nItem][j]);
			    AfxMessageBox(hint);
			    return;
			}
		}
	for (UINT j=0; j<nR; j++)
	{
		if (Request[j]>Available[j])
		{
			hint.Format("出错!资源%d余量(%d)小于申请量(%d)!",j,Available[j],Request[j]);
			AfxMessageBox(hint);
			return;
		}
	}

		//改变Avilable、Allocation、Need的值
		for (UINT j=0; j<nR; j++)
		{
			Available[j] = Available[j]-Request[j];
			Allocation[nItem][j] = Allocation[nItem][j]+Request[j];
			Need[nItem][j] = Need[nItem][j]-Request[j];
			Work[j] = Available[j];
		}

		bool release = true;
		for (UINT j=0; j<nR; j++)
		{
			if (Need[nItem][j]!=0)
			{
				release = false;
			    break;
			}
		}

		if(release)
		{
			for (UINT j=0; j<nR; j++)
			{
				Work[j] += Allocation[nItem][j];
                Available[j] += Allocation[nItem][j];
				Allocation[nItem][j] = 0;
				MAX[nItem][j] = 0;
			}
			Release[nItem] = true;
			nRelease += 1;
			hint.Format("进程%d已完成退出,以后不必再为其分配资源!",nItem);
			AfxMessageBox(hint);
		}

		if(!Safe())
		{
			hint.Format("不能为进程%d分配所申请的资源\n否则将造成不安全状态!",nItem);
			AfxMessageBox(hint);
			//恢复数据 
			for (UINT j=0; j<nR; j++)
			{
				Available[j] = Available[j]+Request[j];
				Allocation[nItem][j] = Allocation[nItem][j]-Request[j];
				Need[nItem][j] = Need[nItem][j]+Request[j];
				Work[j] = Available[j];
			}
		}
		else
		{
			hint.Format("");
			UINT i;
			if(nP>nRelease)
			{
				UINT temp = nP-nRelease-1;
				for (i=0; i<temp; i++)
				  {
					  CString temp;
					  temp.Format("P%d-->",Path[i]);
					  hint += temp;
				  }
				CString cs;
				cs.Format("P%d",Path[i]);
				hint += cs;	
			}
			GetDlgItem(IDC_SAFE)->SetWindowTextA(hint);
		}

	  for(UINT i=0; i<nR; i++)
	   {
		  hint.Format("%d",this->Available[i]);
		  listCtrl.SetItemText(1,i+1,hint);
	   }
	  record -= (record%2)? 1:0;
	  for(UINT j=1; j<=nR; j++)
	   {
		  hint.Format("%d",this->Allocation[nItem][j-1]);
		  listCtrl.SetItemText(record,j,hint);
		  hint.Format("%d",this->MAX[nItem][j-1]);
		  listCtrl.SetItemText(record+1,j,hint);
	   }

}

void ListDialog::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	this->Allot();
	// TODO: Add your control notification handler code here
	*pResult = 0;
}

void ListDialog::OnBnClickedNew()
{
	UINT** allocation = new UINT*[nP+1];
	for(UINT i=0; i<nP+1; i++)
		allocation[i] = new UINT[nR];
	UINT** max = new UINT*[nP+1];
	for(UINT i=0; i<nP+1; i++)
		max[i] = new UINT[nR];
	UINT** need = new UINT*[nP+1];
	for(UINT i=0; i<nP+1; i++)
		need[i] = new UINT[nR];
	UINT* path = new UINT[nP+1];
	bool* release = new bool[nP+1];

	for(UINT i=0; i<nP; i++)
	{
		for(UINT j=0; j<nR; j++)
		{
			allocation[i][j] = Allocation[i][j];
			max[i][j] = MAX[i][j];
			need[i][j] = Need[i][j];
		}
		path[i] = Path[i];
		release[i] = Release[i];
	}

	for(UINT i=0; i<nP; i++)
		delete []Allocation[i];
	delete []Allocation;

	for(UINT i=0; i<nP; i++)
		delete []MAX[i];
    delete []MAX;

	for(UINT i=0; i<nP; i++)
		delete []Need[i];
	delete []Need;
	delete []Path;
	delete []Release;

	Allocation = allocation;
	MAX = max;
	Need = need;
	Path = path;
	Release = release;

	CString hint = _T("");
	hint.Format("请输入P%d对各类资源的最大需求!",nP);
	RsDialog* rd = new RsDialog(NULL,nP,nR,hint);
	do
	{
		if(rd->DoModal()==IDOK && rd->boolean)
			for(UINT j=0; j<nR; j++)
			{
				Allocation[nP][j] = 0;
				MAX[nP][j] = rd->Data[j];
				Need[nP][j] = MAX[nP][j];
			}
		else
			return;
	}while(!rd->boolean);
	Release[nP] = false;

	CString str;
	str.Format("P%d  已  占",nP);
	listCtrl.InsertItem((nP+1)*2,str);
	for(UINT j=1; j<=nR; j++)
	 {
	  str.Format("%d",this->Allocation[nP][j-1]);
	  listCtrl.SetItemText((nP+1)*2,j,str);
	 }
	str.Format("P%d  总  需",nP);
	listCtrl.InsertItem((nP+1)*2+1,str);
	for(UINT j=1; j<=nR; j++)
	 {
	  str.Format("%d",this->MAX[nP][j-1]);
	  listCtrl.SetItemText((nP+1)*2+1,j,str);
	 }

	nP++;

	if(Safe())
	{
		GetDlgItem(IDC_EDIT1)->SetWindowTextA(_T(" √"));
		
		CString path = _T("");
		UINT i;
		if(nP>nRelease)
		{
			for (i=0; i<nP-1; i++)
			{
				CString cs;
				cs.Format("P%d-->",Path[i]);
				path += cs;
			}
			CString cs;
			cs.Format("P%d",Path[i]);
			path += cs;
		}
		GetDlgItem(IDC_SAFE)->SetWindowTextA(path);
	}
	else
	{
		GetDlgItem(IDC_EDIT1)->SetWindowTextA(_T("  X"));
		GetDlgItem(IDC_SAFE)->SetWindowTextA(_T(""));
	}
	// TODO: Add your control notification handler code here
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -