📄 mainfrm.cpp
字号:
#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 + -