1. 程式人生 > >(作業系統)程序排程的設計與實現

(作業系統)程序排程的設計與實現

一、   需求分析

1、採用一種熟悉的語言,如C、PASCAL或C++等,編制程式,最好關鍵程式碼採用C/C++,介面設計可採用其它自己喜歡的語言。    

2、採用多級反饋佇列排程演算法進行程序排程。 

3、每個程序對應一個PCB。在PCB 中包括程序識別符號pid、程序的狀態標識 status、程序優先順序priority、程序的佇列指標 next 和表示程序生命週期的資料life(在實際系統中不包括該項)。 

4、建立程序時即建立一個PCB,各個程序的pid都是唯一的,pid是在1到100 範圍內的一個整數。可以建立一個下標為1到100的布林陣列,“真”表示下標對應的程序標識號是空閒的,“假”表示下標對應的程序標識號已分配給某個程序。 

5、程序狀態status的取值為“就緒ready”或“執行run”,剛建立時,狀態為“ready”。被程序排程程式選中後變為“run”。 

6、程序優先順序priority是0到49範圍內的一個隨機整數。     

7、程序生命週期life是1到5範圍內的一個隨機整數。 

8、初始化時,建立一個鄰接表,包含50 個就緒佇列,各就緒佇列的程序優先順序priority分別是0到49。     

9、為了模擬使用者動態提交任務的過程,要求動態建立程序。進入程序排程迴圈後,每次按ctrl+f即動態建立一個程序,然後將該PCB插入就緒佇列中。按 ctrl+q退出程序排程迴圈。 

10、在程序排程迴圈中,每次選擇優先順序最大的就緒程序來執行。將其狀態從就緒變為執行,通過延時一段時間來模擬該程序執行一個時間片的過程,然後優先順序減半,生命週期減一。設計圖形使用者介面GUI,在視窗中顯示該程序和其他所有程序的 PCB 內容。如果將該執行程序的生命週期不為 0,則重新把它變為就緒狀態,插入就緒佇列中;否則該程序執行完成,撤消其PCB。以上為一次程序排程迴圈。

二、詳細設計

1、資料結構

  struct PCB { 

   intpid;//程序識別符號 

   boolstatus;//程序的狀態 

   intpriority;//程序優先順序 

   intlife;//程序生命週期

};

2、演算法流程圖


三、 軟體測試              

1、初始化

包含50個就緒佇列,各就緒佇列的程序優先順序priority取值是0到49,pid唯一。生命週期life是1到5範圍內的一個隨機整數。如圖1所示:


圖1.初始化

1、Ctrl+f新建程序

按下Ctrl+f後,數目發生變化,由按下Ctrl+f的次數決定,如圖2所示的是按下了2次後的結果:


圖2.Ctrl+f新建程序

1、Ctrl+q退出程序

按下Ctrl+q後,彈出退出程式頁面,即可退出程式,如圖3所示:


圖三.Ctrl+q退出程式

三、 總結

在編寫軟體的過程當中,演算法用了大部分的時間。為了實現實驗當中所要求的功能,使用了大量的時間來思考各種功能所需的演算法。而且,由於對MFC的使用不熟悉,所以多次上網查詢解決方法和請教同學,終於經過努力,將程式寫了出來,體會到了前所未有的成就感。亦在編寫程式的過程當中,加深了對程序排程的理解。不過,在這個過程中,也發現了自己的不足,就是自己不善於編寫演算法,還有技術不夠純熟,不能輕易地將程式編寫出來。

附件:原始碼

struct PCB {  
	int pid;//程序識別符號  
	bool status;//程序的狀態  
	int priority;//程序優先順序  
	int life;//程序生命週期 
};

// Construction
public:
	  void Initialize();//初始化
      void arrange(); 
      PCB pcb[100]; //程序塊
	  bool flag[100];
      int number;//記錄當前程序數
	CMyDlg(CWnd* pParent = NULL);	// standard constructor

BOOL CMyDlg::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


	 m_datalist.ModifyStyle(0, LVS_REPORT); 
     m_datalist.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);//當選中某行時全選  
	 m_datalist.InsertColumn(0,"    pid");  
	 m_datalist.InsertColumn(1,"    status");  
	 m_datalist.InsertColumn(2,"   priority");  
	 m_datalist.InsertColumn(3,"     life");  
	 for (int i=0;i<4;i++)  
	     m_datalist.SetColumnWidth(i,100);//設定列表框列的寬度 
	 number=0; 
	 for(i=0;i<100;i++)
		flag[i]=false;
	 Initialize();
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMyDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	
    
	PCB x; 
    CString s;  
    m_datalist.SetItemText(0,1,"run"); 
    if(pcb[0].life>1) 
	{ 
        pcb[0].priority=pcb[0].priority/2;//優先順序減半
        pcb[0].life-=1;  //生命週期減1
		pcb[0].status=0;//就緒狀態
        for(int j=0;j<number-1;j++) //插入就緒佇列
		{ 
            if(pcb[j].priority<pcb[j+1].priority)
			{ 
                 x=pcb[j]; 
                 pcb[j]=pcb[j+1]; 
                 pcb[j+1]=x;  
			}  
			else break;
		} 
        for(int i=0;i<number;i++) 
		{ 
           s.Format("%d",pcb[i].pid);
           m_datalist.SetItemText(i,0,s); 
           if(i!=0)  
              s="ready";  
           else 
              s="run";  
           m_datalist.SetItemText(i,1,s); 
           s.Format("%d",pcb[i].priority);
           m_datalist.SetItemText(i,2,s); 
           s.Format("%d",pcb[i].life);
           m_datalist.SetItemText(i,3,s);  
		}  
	}  
    else 
	{ 
        m_datalist.DeleteItem(0);
        number--;  
		flag[pcb[0].pid]=false;
        for(int i=0;i<number;i++) 
           pcb[i]=pcb[i+1];  
	}
	m_edit1=number;
	UpdateData(false);
	CDialog::OnTimer(nIDEvent);
}

//程序初始化 
void CMyDlg::Initialize() {  
	CString s; 
	int i;
	//50個程序
	for(i=0;i<50;i++)  
	{  
		pcb[number].status=0; 
		pcb[number].life=1+(int)rand()%4+1;  
		pcb[number].priority=(int)rand()%50;    
		pcb[number].pid=i+1;   
		flag[number]=true;    
		number++;  
	} 	
	arrange(); 
	SetTimer(1,1000,NULL); 
}

void CMyDlg::arrange() 
{  
	int i,j;
	PCB x;  
	CString s; 
	//氣泡排序法按程序的優先順序排序
	for(i=0;i<number-1;i++)  
	{   
		for(j=0;j<number-i-1;j++)   
		{    
			if(pcb[j].priority<pcb[j+1].priority)    
			{     
				x=pcb[j];     
				pcb[j]=pcb[j+1];     
				pcb[j+1]=x; 
			}//if 
		}//for 
	}//for 
	for(i=0;i<number;i++)  
	{   
		m_datalist.InsertItem(number,"");
		s.Format("%d",pcb[i].pid);   
		m_datalist.SetItemText(i,0,s);   
		if(pcb[i].status==0)    
			s="ready"; 
		else    
			s="run"; 
		m_datalist.SetItemText(i,1,s);   
		s.Format("%d",pcb[i].priority);   
		m_datalist.SetItemText(i,2,s);   
		s.Format("%d",pcb[i].life);   
		m_datalist.SetItemText(i,3,s); 
	}//for 
	s.Format("%d",number);   
	m_edit1=number;//顯示程序數量
	UpdateData(false);
}

BOOL CMyDlg::PreTranslateMessage(MSG* pMsg) 
{
	// TODO: Add your specialized code here and/or call the base class
	//ctrl+f新建程序,ctrl+q退出程式
		if(pMsg->message==WM_KEYDOWN)  
	{   
		switch(pMsg->wParam)   
		{   
		case 'F':    
			{     
			//	if(::GetKeyState(VK_CONTROL)<0)    
				{  
					srand((unsigned)time(0));      
					CString s; 
					pcb[number].status=0; 
					pcb[number].life=1+(int)rand()%4+1;    
					pcb[number].priority=(int)rand()%50; 
					for(int i=0;i<100;i++)      
					{       
						if(flag[i]==false)      
						{       
							pcb[number].pid=i+1;        
							flag[i]=true;        
							break; 
						}
					} 
				    number++;
					arrange(); 
					SetTimer(1,2000,NULL);     
					break; 
				} 
			}//case 'F' 
		case 'Q':  
			if(MessageBox("ARE YOU SURE TO EXIT?","提示",MB_YESNO)==IDYES)::PostQuitMessage(0); 
			break; 
		}//switch 
	}
	return CDialog::PreTranslateMessage(pMsg);
}



相關推薦

作業系統程序排程設計實現

一、   需求分析 1、採用一種熟悉的語言,如C、PASCAL或C++等,編制程式,最好關鍵程式碼採用C/C++,介面設計可採用其它自己喜歡的語言。     2、採用多級反饋佇列排程演算法進行程序排程。  3、每個程序對應一個PCB。在PCB 中包括程序識別符號pid

MVC實戰之排球計分—— Controller的設計實現

需要 strong 技術 ret web src alt 點擊 cnblogs 控制器 控制器接受用戶的輸入並調用模型和視圖去完成用戶的需求。所以當單擊Web頁面中的超鏈接和發送HTML表單時, 控制器本身不輸出任何東西和做任何處理。它只是接收請求並決定調用哪個模型構件去處

挑戰408——作業系統9——程序的同步互斥

作業系統中的併發程序有些是獨立的有些需要相互協作,獨立的程序在系統中執行不影響其他程序,也不被其他程序影響(因為他們沒有共同需要一起用到的資源)。而另外一些程序則需要與其他程序共享資料,以完成一項共同的任務。 因此,為了保證作業系統的正常活動,使得程式的執行具有

作業系統實驗課程序的建立銷燬

根據老師給的實驗指導書做的 # include <stdio.h> # include <stdlib.h> # include <Windows.h> int

例項:tasklet實現軟中斷學習《Linux核心設計實現》記錄

tasklet是通過軟中斷實現的,tasklet本身也是軟中斷。 關於tasklet更詳細的知識,還是建議看一下《Linux核心設計與實現》 本貼子只介紹一下具體的流程。 驅動程式原始碼: #include <linux/init.h> #include <linu

例項:基於4412-實現新增自己的系統呼叫函式學習《Linux核心設計實現》 記錄

學習筆記: 在學習《linux核心設計與實現》過程中,瞭解到: 在Linux中,系統呼叫是使用者空間訪問核心的唯一手段(除異常和陷入之外)。 系統呼叫主要有三個作用: ①:為使用者空間提供一個硬體的抽象介面。 ②:系統呼叫保證了系統的穩定和安全。 ③:為了實現多工和虛擬記憶體(應用程

[連載]《C#通訊串列埠和網路框架的設計實現》- 0.前言

                              目       錄 前言 前言       剛參加工作,使用過VB、VC開發軟體,隨著C#的崛起,聽說是C++++,公司決定以後開發軟體使用C#,憑藉在書市5塊錢買C#程式設計入門書籍,開始了職業生涯。開發C/S、B/S結構的軟體是

[連載]《C#通訊串列埠和網路框架的設計實現》-2.框架的總體設計

目       錄 C#通訊(串列埠和網路)框架的設計與實現... 1 (SuperIO)- 框架的總體設計... 1 第二章           框架總體的設計... 2 2.1           宿主程式設計... 2 2.2           通訊機制設計... 7   2.2.1   

[連載]《C#通訊串列埠和網路框架的設計實現》-1.通訊框架介紹

目       錄 第一章           通訊框架介紹... 2 1.1           通訊的本質... 2 1.2           框架簡介... 3 1.3           解決現實問題... 4 1.4           應用場景... 5 1.5       

[連載]《C#通訊串列埠和網路框架的設計實現》- 12.二次開發及應用

目       錄 第十二章     二次開發及應用... 2 12.1        專案配製... 3 12.2        引用相關元件... 4 12.3        構建主程式... 5 12.4        裝置驅動的開發... 6 12.4.1       假定通訊協議...

作業系統之——程序 1程序的描述控制

鋪墊 程式順序執行的特徵: 1.順序性:處理機按照規定的順序執行,每一操作必須在下一操作開始前結束。 2.封閉性:程式執行時獨佔全機資源,資源狀態只有本程式才可以改變,一旦開始執行,結果不受外界因

MVC排球計分——程序截圖運行結果

cnblogs 開始 img mage 結果 界面 詳細 插入數據 技術分享 開始輸入隊伍名字 計分界面 比賽記錄插入數據庫 詳細記錄 MVC排球計分(七)——程序截圖與運行結果

Linux常用命令程序的安裝管理

rpm 編譯安裝 侯良金 linux 安裝軟件 Linux常用命令(四)程序的安裝與管理一、Linux應用程序基礎1、Linux應用程序的組成■普通的可執行程序文件。一般保存在“/usr/bin”目錄中,普通用戶即可執行。■服務器程序、管理程序文件。一般保存在“/usr/sbin”

Spark學習——RDD的設計運行原理

center data 創建 組成 分享圖片 img medium 列操作 信息 Spark的核心是建立在統一的抽象RDD之上,使得Spark的各個組件可以無縫進行集成,在同一個應用程序中完成大數據計算任務。RDD的設計理念源自AMP實驗室發表的論文《Resilient

DSL 系列2 - 外掛的論述實現

前言 本文主要探討基於 DSL(domain specific language) 之上的外掛設計,他們是領域的附屬,為領域提供額外的服務,但領域不依賴於他們。 1. 論述 領域應當儘可能地去專注他的核心業務規則,應當儘可能地與其他輔助性的程式碼解耦,一些通用的功能可以耦合進框架或者設計為中介軟體;但

樹堆Treap圖文詳解實現

1.Treap的定義 樹堆(Treap)是二叉排序樹(Binary Sort Tree)與堆(Heap)結合產生的一種擁有堆性質的二叉排序樹。 但是這裡要注意兩點,第一點是Treap和二叉堆有一點不同,就是二叉堆必須是完全二叉樹,而Treap並不一定是;第二

Docker學習總結29——Docker核心技術實現原理

提到虛擬化技術,我們首先想到的一定是 Docker,經過四年的快速發展 Docker 已經成為了很多公司的標配,也不再是一個只能在開發階段使用的玩具了。作為在生產環境中廣泛應用的產品,Docker 有著非常成熟的社群以及大量的使用者,程式碼庫中的內容也變得非常龐大。同樣,由於

Java併發程式設計的藝術筆記——ConcurentHashMap的原理實現

一.執行緒不安全的HashMap 多執行緒環境下,使用HashMap進行put操作會引起死迴圈(jdk1.7 Entry連結串列形成環形資料結構),導致CPU利用率接近100%。 二.效率低下的HashTable 多個執行緒訪問HashTable的同步方法,會引起阻塞或輪詢狀態。 三.Concurre

Java學習筆記8 -Java GUI設計事件處理

第八章 Java GUI設計與事件處理 1、題目 1.1、 如何來製作圖形介面?它需要引入哪些包 建立視窗並在視窗中新增各種元件,指定元件的屬性和它們在視窗中的位置,從而構成圖形介面的外觀效果。定義圖形介面的事件和各種元件對不同事件的響應,從

【Android View事件】View滑動實現滑動的幾種方法

1 前言 在前面的幾篇文章,我向大家介紹的都是單一View事件,而在這篇文章中,我將向大家介紹連續的事件 —— 滑動。 在安卓裝置上滑動幾乎是應用的標配,由於安卓手機螢幕較小,為了給使用者呈現更多的內容,就需要使用滑動來隱藏和顯示一些內容。