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

📄 mainfrm.cpp

📁 这是软件工程的关于模拟进程调度的课程论文
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include "ProcessManager.h"
void CMainFrame::OnTimer(UINT nIDEvent) 
{
	if(cpuState==CPU_RUN)
	{
		this->Schedule();

		WaitForSingleObject(hMutex,INFINITE);
		if(QueueList->next!=QueueList)
		{
			if((this->GetActiveView()->GetRuntimeClass()) == RUNTIME_CLASS(CMyListView))
			{
				((CMyListView*)this->GetActiveView())->AddNewItems(QueueList);
			}
			else
				((CMyListView*)this->GetActiveView())->AddNewItems(NULL);
		}				
		else
		{
			((CMyListView*)this->GetActiveView())->AddNewItems(NULL);
			cpuState = CPU_STOP;
		}

		ReleaseMutex(hMutex);
	}

	//::SendMessage(this->GetActiveView()->m_hWnd,WM_TIMER,0,0);

	CFrameWnd::OnTimer(nIDEvent);
}

UINT CMainFrame::BuildActiveQueue()
{
	int i = 0;
	int counter = 0;
	struct PCB* pstart = NULL;
	struct QueueNode * pQueue = NULL;
	
	WaitForSingleObject(hMutex,INFINITE);

	/*
	 * 建立起一个就绪状态队列
	 */
	for(i = 0; i < 256; i++)	
	{
		pstart = pcblist[i];
		while(pstart)//有一个准备好的进程	
		{
			/*
			 * if(pstart->state==PS_READY)
			 */
			AdjustProcess(pstart);

			if(pstart->state==PS_READY)
			{
				pQueue = new QueueNode(pstart); 
				if(this->AddQueueNode(pQueue)!= pstart->nid)
				{
					//::AfxMessageBox("Error while build active Queue!");
					ReleaseMutex(hMutex);
					return -1;
				}
				counter++;
			}
			pstart = pstart->next;
		}
	}
	
	/********************************
	pQueue = QueueList->next;
	CString str = _T("");

	while(pQueue!=QueueList)
	{
		str += pQueue->ppcb->strname;
		pQueue = pQueue->next;
	}
	::AfxMessageBox(str);
	********************************/
	ReleaseMutex(hMutex);

	return counter;
}

void CMainFrame::OnCpuStart() 
{
	// TODO: Add your command handler code here
	cpuState = CPU_RUN;	
}

void CMainFrame::OnCpuStop() 
{
	// TODO: Add your command handler code here
	cpuState = CPU_STOP;
}

void CMainFrame::OnDestroy() 
{
	CFrameWnd::OnDestroy();
	
	// TODO: Add your message handler code here

	KillTimer(m_nTimer);
}



//进行新进程的入队操作
UINT CMainFrame::AddNewPCB(struct PCB *pnew)
{
	
	if(!pnew)	return 0;	//错误返回

	WaitForSingleObject(hMutex,INFINITE);

	struct PCB *pstart = pcblist[pnew->priority];//队列头
	if(!pstart)	//队头插入
	{
		pcblist[pnew->priority] = pnew;
		//pnew->prev = (&pcblist[ppi->nprio]);
	}
	else		//队中插入
	{
		while(pstart->next!=NULL)
		{
			pstart = pstart->next;
		}
		pnew->next = pstart->next;
		pstart->next = pnew;	//后继指针
		pnew->prev = pstart;	//前导指针
	}
	ReleaseMutex(hMutex);

	return pnew->nid;
}



//从文件中读取记录
void CMainFrame::OnReadfile() 
{
	// TODO: Add your command handler code here
	FILE * fp = NULL;
	char buffer[128];
	char name[16];
	UINT prio;
	UINT time;
	struct PCB * pnew = NULL;
	
	fp = fopen("info.txt","r");

	if(!fp)	
	{
		::AfxMessageBox(" 读取文件失败。  ");
		return ;
	}

	fgets(buffer,128,fp);

	while(fgets(buffer,128,fp))
	{
		int i = 0;
		CString str;
		while(buffer[i]!='\t')
		{
			name[i] = buffer[i];
				i++;
		}
		name[i] = '\0';
		str.Format("%s",name);

		i++;
		prio = 0;
		while(buffer[i]!='\t')
		{
			prio = prio*10+((UINT)buffer[i]-48);
			i++;
		}

		i++;
		time = 0;
		while(buffer[i]!='\n')
		{
			time = time*10 + ((UINT)buffer[i]-48);
			i++;
		}
		
		if(prio>10)	prio = 10;

		if(time<0)	time = 100;

		pnew = new PCB(prio,time,++UPID,str);
		this->AddNewPCB(pnew);

	}
	fclose(fp);
	::AfxMessageBox(" 读取文件成功。     ");
}

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	BOOL bRet;
	
	if(!m_Splitwnd.CreateStatic(this,2,1))	return FALSE;

	bRet = m_Splitwnd.CreateView(0,0,RUNTIME_CLASS(CMyListView),CSize(50,250),pContext);
	if(!bRet)	return FALSE;
	//再创建一个视图以静态的观看结果
	bRet = m_Splitwnd.CreateView(1,0,RUNTIME_CLASS(CMyListView),CSize(50,30),pContext);
	if(!bRet)	return FALSE;
	

	return TRUE;

	//return CFrameWnd::OnCreateClient(lpcs, pContext);
}


//进程挂起
void CMainFrame::OnSuppond() 
{
	// TODO: Add your command handler code here
	CSetDialog *pSetDlg = new CSetDialog(this);
	
	ASSERT(pSetDlg!=NULL);
	pSetDlg->Create(IDD_NEWDLG);
	::SendMessage(pSetDlg->m_hWnd,UM_RECEIVEINFO,0,MODE_SUPPOND);	//发送挂起消息
	pSetDlg->ShowWindow(SW_RESTORE);
}


/*
 * 增加循环的链表节点的操作
 */
UINT CMainFrame::AddQueueNode(QueueNode *queuenode)
{
	IASSERT(queuenode!=NULL);
	struct QueueNode* pCur = this->QueueList->next;

	
	while(pCur!=QueueList)	//若非头指针
	{
		//动态优先级的在前面
		if(pCur->ppcb->dynprio > queuenode->ppcb->dynprio)//比较动态优先级
			pCur = pCur->next;
		else
			break;
	}
	
	//在pCur前面执行插入操作
	queuenode->next = pCur->prev->next;
	pCur->prev->next = queuenode;
	queuenode->prev = pCur->prev;
	pCur->prev = queuenode;

	queuenode->ppcb->state = PS_ACTIVE;	//设置其状态为运行队列状态

	return queuenode->ppcb->nid;

}

/*
 * 删除循环链表结点的操作
 */
struct QueueNode* CMainFrame::DelQueueNode(const struct PCB *ppcb)
{
	IASSERT(ppcb!=NULL);
	
	struct QueueNode* pCur = this->QueueList->next;
	while(pCur!=QueueList)
	{
		if(pCur->ppcb != ppcb)
			pCur = pCur->next;
		else
			break;
	}

	//IASSERT(pCur->ppcb!=NULL);
	if(pCur!=QueueList)
	{
		pCur->next->prev = pCur->prev;
		pCur->prev->next = pCur->next;
		pCur->next = pCur->prev = NULL;
	}

	return pCur;
}


//返回时间片长度
UINT CMainFrame::AdjustProcess(PCB *ppcb)
{	
	float balance =0.0;
	ASSERT(ppcb!=NULL);
	if(ppcb->state == PS_READY||ppcb->state == PS_RUNNING)
		ppcb->state = PS_ACTIVE;

	if(ppcb->state == PS_NOTHING)
		ppcb->state = PS_READY;


	//设置应该分配的时间片长度
	balance = (float)(ppcb->total_time-ppcb->current_time)/ppcb->total_time;

	//根据总时间、已经运行时间、等待时间及优先级分配动态优先级
	ppcb->dynprio = UINT(ppcb->priority*balance)+ppcb->wait_time*3;

	//设置动态优先级的上限
	if(ppcb->dynprio>50)	ppcb->dynprio = 50;
	if(ppcb->dynprio<=0)	ppcb->dynprio = 5;
	
	

	return (ppcb->dynprio);
}


//调度过程
UINT CMainFrame::Schedule()
{
	int i = 0;
	int Looptime = LOOPTIME;
	struct QueueNode* ptemp = NULL;

	//若无新的进程,并且运行队列中没有可运行的进程则提示无进程
	if(BuildActiveQueue()<=0 && QueueList->next==QueueList)	
	{
		//AfxMessageBox("当前无进程存在!");
		this->cpuState = CPU_STOP;
		return 0;
	}

	WaitForSingleObject(hMutex,INFINITE);
	pCurrent = QueueList->next;

	while(pCurrent!=QueueList)
	{
	
		ASSERT(pCurrent->ppcb!=NULL);
		//if(!pCurrent->ppcb)	break;

		/*
		 * 当调度周期没有结束
		 * 并且分配的时间片未结束
		 * 并且进程未结束
		 * 则继续运行
		 */
		while((Looptime>0)&&(pCurrent->ppcb->dynprio>0)
			&&(pCurrent->ppcb->current_time < pCurrent->ppcb->total_time))
		{
			/*
			 * 检测是否存在由于中断或其他原因
			 * 而需要退出运行队列的元素:
			 * 若有,则将其删除,
			 * 若无,则给进程分配时间片运行
			 */
			if((pCurrent->ppcb->state!=PS_ACTIVE)&&(pCurrent->ppcb->state!=PS_RUNNING))
			{
				ptemp = pCurrent->prev;		//保护运行队列现场
				//从队中移除,但并未从存储结构中删除
				DelQueueNode(pCurrent->ppcb);
				pCurrent = ptemp->next;		//恢复运行队列现场
			}
			else
			{
				IASSERT(pCurrent->ppcb!=NULL);
				pCurrent->ppcb->dynprio--;
				pCurrent->ppcb->current_time++;
				Looptime--;
			}
		}

		/*
		 * 说明:删除一个已经结束的进程,删除两部分信息
		 *       
		 *  1.删除运行队列的信息
		 *  2.删除存储队列的信息
		 */
		if(pCurrent->ppcb->current_time == pCurrent->ppcb->total_time)
		{
			ptemp = pCurrent->prev;		//保护运行队列现场
			//从存储结构及运行队列中删除
			SearchByPid(pCurrent->ppcb->nid,MODE_KILL);
			pCurrent = ptemp->next;		//恢复运行队列现场
		}
		
		/*
		 * 判断是否存在没得到CPU运行的进程,如果存在,则执行操作:
		 *
		 * 1.将运行队列中没有得到运行的进程向前移动,提高其运行优先级别
		 * 2.重新调整运行队列
		 * 3.若进程已经是二次运行则不进行调整
		 */
		if(Looptime<=0)	//时间片分配完成
		{
			ptemp = pCurrent->next;
			while(ptemp!=QueueList)//遍历未运行进程,查找未运行元素
			{
				if(ptemp->ppcb->dynprio==0)	//二次运行的进程不调整
					break;
				ptemp->ppcb->wait_time++;	//设置未循环的进程的等待时间增加
				AdjustProcess(ptemp->ppcb);	//重新调整动态优先级别
				ptemp = ptemp->next;
			}
			AdjustQueue();//重新调整运行队列

			break;
		}
		else//若时间片未分配完成,则继续循环
		{
			pCurrent = pCurrent->next;

			if(pCurrent->next==pCurrent)//若只有一个元素则停止
				break;
			
			if(pCurrent==QueueList)		//跳过循环,继续
			{
				pCurrent = pCurrent->next;
				ptemp = pCurrent;
				while(ptemp!=QueueList)//重新处理整个队列
				{
					IASSERT(ptemp->ppcb!=NULL);
					AdjustProcess(ptemp->ppcb);//需要重新设置实时优先级
					ptemp = ptemp->next;
				}
			}
		}
		i++;
	}
	//设置当前运行的进程的状态值为运行
	if(pCurrent->ppcb)		pCurrent->ppcb->state = PS_RUNNING;
	ReleaseMutex(hMutex);

	return i;
}


//调整循环链表
UINT CMainFrame::AdjustQueue()
{
	struct QueueNode * ptail = QueueList->prev;
	struct QueueNode * pmid = pCurrent->next;

	if(pCurrent->ppcb!=NULL)
	{
		if(pCurrent->next!=QueueList)
		{
			//队列大转移
			pCurrent->next = QueueList;
			pmid->prev = QueueList;
			QueueList->next->prev = ptail;
			ptail->next = QueueList->next;
			QueueList->next = pmid;
			QueueList->prev = pCurrent;

			return (pCurrent->ppcb->nid);
		}
	}

	return 0;
}

⌨️ 快捷键说明

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