張瓊聲 蔣玉新 李春華 劉童璇
摘要:進程是資源分配和獨立運行的基本單位,是操作系統的核心概念。“操作系統”教學中,進程的概念以及進程管理的實現原理抽象難懂,初學者難以掌握。本文闡述如何以圖形化方式設計和實現進程管理的演示系統,以輔助課堂教學。該系統的演示內容包括:進程的概念、進程創建、進程組織、進程關系管理、進程阻塞、進程喚醒、進程撤銷、進程調度、進程同步。
關鍵詞:進程管理;演示系統;操作系統
中圖分類號:G642 文獻標識碼:B
1前言
進程管理是操作系統原理最主要的教學內容之一,而進程及進程的控制原理是學生學習的重點和難點。如何使學生能夠在較短的時間內,深入了解進程的概念及進程控制的原理,如何把進程的概念與程序運行的軟硬件環境的變化聯系起來?如何把進程管理的功能與數據結構和算法的實現結合起來?使學生從根本上掌握進程的概念,理解操作系統中進程管理功能的實現原理和實現技術,把抽象的理論與具體的實現技術結合起來?是“操作系統”課程教學面臨的重要問題。
進程管理演示系統主要用于輔助課堂教學,試圖將抽象的理論與系統設計、實現的具體技術相結合,通過動態的、圖形化的界面表現進程概念的本質、進程管理的過程、進程管理功能與數據結構和算法實現的關系。把抽象的概念和原理實例化。幫助學生直觀地、深入地理解進程的概念和進程管理功能存在的必要性以及相應的實現技術。
本系統主要實現進程概念、進程控制、進程調度、進程同步行為和實現原理的演示。該系統的特點是用圖形化的方式把操作系統原理與程序實現結合起來。論文詳細說明了該演示系統的設計方案與實現技術。
2系統設計
2.1系統模塊結構
本系統包括進程概念、進程控制、進程調度、進程同步四個演示模塊。其中進程控制演示模塊包括進程創建、進程終止、進程阻塞與喚醒三個演示子模塊。進程調度演示模塊包括單級隊列調度和多級隊列調度演示兩個子模塊。進程同步演示模塊包括進程互斥和讀者—寫者問題演示兩個子模塊。
本系統用VC++6.0開發,采用單文檔結構,所有演示過程都在視圖中通過VC控件交互實現。系統使用了延時機制,每當執行一個過程使界面發生變化或執行了關鍵步驟后,執行一個延時函數,從而給用戶足夠的時間觀察界面的變化。
2.2進程組織
(1) 鏈表組織
本系統實現多個進程鏈表,包括總進程鏈表、多個優先權不同的就緒進程鏈表和三個對應不同阻塞事情的阻塞進程鏈表。
(2) 進程樹
系統按照進程的親屬關系,建立進程樹,實現了進程樹的管理和圖形顯示。
(3) 進程標識符PID的管理
每一個進程都有唯一的內部標識符PID,本系統通過循環使用來達到有限PID資源的合理利用。當進程創建時分配可用的PID,當進程終止時,釋放占用的PID。
2.3進程執行過程的模擬
本系統通過定時器和執行時間來模擬進程的執行過程。
創建進程時,給進程一個隨機的執行時間。執行時間長短根據系統參數配置進行靈活控制。進程同步中對臨界資源的訪問過程也通過訪問時間來模擬,根據進程的執行時間,進程訪問臨界資源的時間總是定義為一個比總執行時間小的值。
給定進程的執行時間后,通過定時器控制進程的執行。進程執行一條指令用一個定時周期來模擬,在定時處理函數中對進程控制塊的相關數據進行修改并同步在界面上更新顯示,從而模擬出進程的執行過程。當定時周期數等于給定的進程執行時間時(本系統在進程控制塊中添加了已執行時間來記錄執行進度,該值就等于定時周期數),進程正常結束。
2.4進程概念演示模塊
本模塊通過顯示當前進程的PCB信息、CPU寄存器的變化來演示進程概念。模擬了進程實體、進程控制塊、動態特征、短暫存在性、進程切換、并發執行、獨立性等特點。
系統界面上顯示的進程信息都直接或間接地從進程控制塊中獲取。
2.5進程控制演示模塊
(1) 進程創建演示模塊
本模塊實現進程創建過程的演示。用戶可以輸入新進程的外部標識符即進程名稱,若用戶沒有輸入,則系統自動為進程命名,每一個進程的創建都是有引發事件的,用戶可以在界面上選擇一個引發進程創建的事件。當用戶點擊“創建進程”按鈕時就開始執行創建進程過程并同步顯示進程創建的每一個執行步驟。
(2) 進程終止演示模塊
本模塊實現并演示各種不同情況下進程終止的過程。用戶可以通過輸入PID來終止某個進程,也可以通過選擇界面上進程列表中的某個進程來終止被選中的進程。執行態進程被終止后要轉進程調度程序。
(3) 進程阻塞與喚醒演示模塊
本模塊實現并演示進程阻塞與喚醒的過程。進程執行過程中用戶可以選擇阻塞事件并阻塞當前進程。當有阻塞態進程時,用戶可以選擇相關事件喚醒阻塞列表中的進程。
本模塊設置了三個阻塞事件:打印機服務、I/O設備操作和無新數據輸入。
2.6進程調度演示模塊
本模塊實現了單級隊列調度和多級隊列調度的演示。分別實現了搶占、非搶占、優先級、時間片等調度策略的模擬。多級隊列調度的演示,模擬了Minix的三級隊列(任務級、服務級和用戶級)調度 ,定義了三個優先級不同的就緒隊列。
2.7進程同步演示模塊
(1) 進程互斥演示模塊
本模塊實現并演示了多個進程互斥訪問同一個臨界資源的控制過程。通過該演示過程,使用戶了解操作系統是如何實現進程對臨界資源的互斥訪問的。
本模塊中,對臨界資源的訪問可以由用戶控制,也可以系統自動控制。即在進程執行過程中,用戶可以發送訪問臨界資源的命令,讓其執行訪問臨界資源的過程。自動控制的設計是若某進程沒有訪問過臨界資源,則令其在執行過程的最后時間段自動訪問臨界資源。
(2) 讀者—寫者問題演示模塊
本模塊演示多個讀進程與寫進程同步訪問共享數據區的管理過程。創建進程時,用戶要指定新進程的類別(讀者進程或寫者進程)。用戶可以通過進程列表選擇任何進程執行,執行過程中,用戶可以隨時讓進程訪問資源。
2.8系統參數配置
本系統為了靈活控制演示過程并滿足用戶的需要,設置了一些配置參數,如定時周期、最小或最大延時時間、最小或最大執行時間、優先級、最大進程數等。
2.9系統界面設計
演示界面設計如圖1所示:

3系統實現
3.1進程控制塊PCB
(1)PCB結構體定義
structPCB
{
//進程標識符信息
UINTnPID; //進程的內部標識符
CString szName; //進程的外部標識符
PCB *pParent; //進程的父進程指針
PCB *pFirstChild; //進程的子進程指針
PCB *pNextSibling; //兄弟進程指針
//處理機狀態信息
DWORD dwPC; //下一條指令地址
DWORD dwPSW; //程序狀態字
DWORD dwCS; //段地址
DWORD dwPageTableAddr; //最外層頁表地址,32位
//進程調度信息
UINT iState; //進程的狀態
UINT iPriority; //進程的優先級
UINT iPriorUpSteps; //優先級動態提升的級數
int nTotalTime; //進程的總執行時間
int nHasExecTime; //進程已經執行的時間
int nWaitTime; //等待時間
UINT iWaitEvent; //等待事件
UINT iCritSrcSort; //進程訪問的臨界資源類別
int nCritSrcTotalT;
//進程訪問臨界資源的總時間
int nCritSrcHasExecT;
//進程已經訪問臨界資源 的時間
UINT iCritSrcVisitPos;
//進程訪問臨界資源的階段
//進程控制信息
int nKernelStackPos;//內核棧指針位置
UINT iUser; //進程的用戶名
UINT iSort; //進程的類別
UINT nWaitedSema; //已經等待過信號量的標志
list_headpTasksList; //進程鏈表的指針
list_head pStateList; //鏈接狀態鏈表的指針
RECT *aAddrSpace[3];//關聯進程三部分模擬空間
};
(2)PCB結構體說明
? 組織進程關系的域
pParent記錄每一個進程的父進程,pFirstChild記錄第一個兒子,pNextSibling記錄下一個兄弟,通過這種方式記錄了整個父子關系樹,進程關系的管理通過這三個域實現。
? 記錄寄存器信息的域
dwPC、dwPSW、dwCS、dwPageTableAddr分別保存了當前CPU中主要的寄存器信息,通過這些信息來管理進程并發執行以及獨立運行。dwPC在每一次定時處理中加1,模擬一條指令的執行,dwPSW在執行過程中隨機變化,模擬指令執行對CPU標志的影響。每個進程的dwCS和dwPageTableAddr值不同且不變,在創建進程時要保證它們的唯一性。
? 優先級
iPriority是進程的優先級。本系統設定了六種優先級,分別為PRIO_REALTIME(實時)、PRIO_HIGHER(高)、PRIO_UPSTANDARD(高于標準)、PRIO_STANDARD(標準)、PRIO_DOWNSTANDARD(低于標準)、PRIO_LOWER(低)。該值是動態的,在某些模塊中,創建進程時系統自動設為PRIO_STANDARD(標準);在某些模塊中,創建進程時由用戶指定。在所有模塊中,每一次進程調度時根據nWaitTime(等待時間)以及系統參數m_nUpPrioSpan(優先級升級的基數,針對等待時間)對就緒進程的iPriority值進行相應的修改,但最高只能升級到PRIO_HIGHER(高)。
? 執行時間
nTotalTime是進程的執行時間,它決定了進程的生存期,用于控制進程的執行。系統進程(0號進程和1號進程)的PCB中,其值為-1,表示進程一直存在。
? 已執行時間
nHasExecTime是進程的已執行時間,用于控制進程的執行進度。進程執行時,在每一次定時處理中加該域值1,當它等于nTotalTime時,表示進程執行完畢。
? 等待時間
nWaitTime是進程的等待時間,用于動態修改進程的優先級,該值在每一次定時處理中加1,但執行態進程的nWaitTime始終為0,只有當執行態進程切換為其它狀態時,才開始累積該值。當進程的狀態發生改變而鏈入到其它狀態鏈表中時,該值清0。
? 等待事件
iWaitEvent是進程的等待事件,本系統將此值的范圍進行了擴充。對于就緒進程,該值為WAIT_CPU(等待CPU);對于執行態進程,該值為WAIT_NULL(沒有等待事件);對于阻塞進程,該值表示阻塞事件,可以取值為WAIT_PRINTER(等待打印機),WAIT_IOSTREAM(等待I/O設備),WAIT_NEWDATA(等待新數據);在進程同步模塊中,對于等待臨界資源的進程該值為WAIT_CRITSRC (等待臨界資源),等待的資源保存在iCritSrcSort中。
? 訪問的臨界資源種類
iCritSrcSort是進程訪問臨界資源的種類,也就是對應的信號量類別。本系統中可以取值為CRITSRC_PRINTER (打印機資源)、CRITSRC_GLOBAL (全局變量資源)、CRITSRC_READWRITE(讀寫資源)。對于不需要訪問臨界資源的進程來說該值為CRITSRC_NULL(無臨界資源)。
? 訪問臨界資源的時間
nCritSrcTotalT是進程訪問臨界資源的總時間,用于控制進程對臨界資源的訪問過程,該值是在進程創建時根據nTotalTime隨機產生的,總是小于nTotalTime。
? 已訪問臨界資源時間
nCritSrcHasExecT是進程已訪問臨界資源的時間,用于控制進程訪問臨界資源的進度,在定時處理中加1,當等于nCritSrcTotalT時表示訪問臨界資源結束,該域主要在進程同步模塊中使用,在其他模塊中該值一律為0。
? 訪問臨界資源的階段
iCritSrcVisitPos是進程對臨界資源的訪問階段,可以取值為CRITSRC_VISIT_NULL(沒有訪問),CRITSRC_ VISIT_ENTEY(進入區)、CRITSRC_VISIT_CRITICAL(臨界區)、CRITSRC_VISIT_EXIT(退出區)、CRITSRC_ VISIT_FINISH(完成訪問),該域用于標識和記錄進程訪問資源階段,在進程同步模塊中使用。
? 內核棧棧頂位置
nKernelStackPos模擬進程的內核棧指針位置,即棧頂位置,創建進程時置為0,模擬進程執行過程中內核棧的變化,該域主要在進程概念演示模塊中使用。
? 進程用戶名
iUser是進程的用戶名,可以取值為SYSTEM(系統)和USER(用戶)。本系統中為了能夠比較全面地模擬操作系統中的進程,設置了0號系統進程和1號系統進程。
? 進程類別
iSort是進程的類別,可以取值為NORMALTASK(一般進程)、READTASK(讀者進程)、WRITETASK(寫者進程),該域主要用于區分進程同步模塊中的讀寫進程,在其他模塊中,該值為NORMALTASK(一般進程)。
? 等待信號量標志
nWaitedSema用于進程同步模塊,用來標識進程訪問臨界資源過程中,是否執行過wait(s)原語,因為當進程申請信號量失敗被阻塞后,它已經對信號量值進行減一操作了,當再次被喚醒時,是從被阻塞的位置往下執行的,即不會再檢查信號量值了,由于本系統是模擬這一過程,需要一個標志來做判斷,而進程訪問臨界資源的過程中可能要涉及多個信號量,所以將nWaitedSema定義為UINT類型,否則會使信號量值發生錯誤。
? 鏈表鏈接域
pTasksList和pStateList用于鏈接進程鏈表,它們都是list_head類型的通用雙向循環鏈表。list_head結構的定義:
structlist_head
{
struct list_head * pPre;
struct list_head * pNext;
PCB * pThisPcb;
};
? 模擬內存空間
aAddrSpace是一個具有三個元素的數組,用來模擬進程的邏輯內存空間,是RECT類型的。本系統用三個矩形模擬進程三部分(正文段、用戶數據段和系統數據段)在內存中的分布,在界面上顯示出來,直觀地表示出進程實體。在進程創建演示中,由于要演示資源分配的過程,所以在進程創建時對該數組進程賦值(根據顯示區域合理的產生隨機值),而其它模塊中,在需要顯示進程實體的分布時才給該數組賦值。
3.2信號量
在進程同步演示模塊中,用到了記錄型信號量。
(1) 信號量結構體定義
structSEMAPHORE
{
int nValue; //資源數量
CProcessLink * pBlockLink; //阻塞鏈表
};
(2) 結構體說明
每一個信號量都有一個標識臨界資源數量的值,即結構體中的nValue。在本系統的進程同步模塊中,用到的都是互斥信號量,所以nValue初值都是1。當該值小于0時,nValue的絕對值表示阻塞鏈表中的等待進程數。
因等待臨界資源而不能繼續執行的進程阻塞相應信號量的阻塞鏈表中,該鏈表就是結構體中的pBlockLink,當進程釋放臨界資源訪問權時,若判斷得出還有等待該資源的進程,就從該鏈表中喚醒第一個進程。
3.3模塊類
模塊類是本系統中實現進程管理系統演示的核心類。由于本系統有多個模塊,且各個模塊具有一些共同特性,所以定義了一個基類CDlgPage,并定義了繼承類CDlgPage的各個模塊或子模塊類,如圖2所示。每個模塊都有一些重要的成員,說明如下:
? m_pCurRunPcb指向當前將要執行的進程或當前正在執行的進程。
? m_nCurTimerEvent記錄定時器定時標志。
? m_pTasksLink指向總進程鏈表。
? m_pSysIdleTask是0號系統進程,m_pSysInitTask是1號系統進程,每個模塊中都有這兩個模擬的系統進程,這兩個進程在第一次演示當前模塊時創建,一直存在。
? m_nProNum是當前模塊中的進程數。
? m_pSysInitTask是1號系統進程。
? m_nProNum是當前模塊中的進程數。
? virtual void InitPage()該函數的功能是在用戶切換到當前模塊時進行一些初始化操作,即控件創建、信息顯示、等操作。
? virtual void ClearPage()該函數的功能是對當前演示模塊進行相關清除操作,即刪除界面控件、清除其它界面顯示、清除模塊對象與標志記錄等操作。
用戶在切換演示模塊時先調用被切換模塊對象的ClearPage()函數,再調用切換到的模塊對象的InitPage()函數,從而實現演示模塊的切換。
4總結
本系統結合多種控件以及延時、同步刷新界面和突出顯示變化效果等實現了圖形化的進程管理模擬系統,達到了較好的演示效果。進程管理中各個模塊獨立實現,能較好地輔助操作系統原理的課堂教學。系統代碼結構清晰,功能豐富,方案設計合理,擴展性強,有良好的交互性,有助于學生直觀、具體地理解進程管理原理。

參考文獻:
[1] 湯子瀛,哲鳳評,湯小丹. 計算機操作系統原理(修訂版)[M].西安:西安電子科技大學出版社,2001:26-79.
[2] 陳莉君. 深入分析Linux內核源代碼[M].北京:人民郵電出版社,2002:97-138.
[3] DANIEL P.BOVET,MARCO CESATI.深入理解Linux內核[M].3版.陳莉君,譯.北京:中國電力出版社,2007:84-134,258-265.
[4] Andrew S.Tanenbaum. 操作系統設計與實現[M]. 北京:電子工業出版社,1998:19-49.