3 进程和线程.docx
- 文档编号:23439328
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:40
- 大小:40.96KB
3 进程和线程.docx
《3 进程和线程.docx》由会员分享,可在线阅读,更多相关《3 进程和线程.docx(40页珍藏版)》请在冰豆网上搜索。
3进程和线程
第三章處理程序與執行緒的描述和排程
這個章節將詳細介紹WindowsCE系統中的處理程序(process)和執行緒(thread),並對WindowsCE作業系統所使用的排程策略進行分析。
處理程序是資源分配的基本單位,而執行緒是排程的基本單位。
這一章的程式碼主要節選於[CEROOT]PRIVATE\WINCEOS\COREOS\NK\KERNEL\目錄的schedule.c、intrapi.c以及[CEROOT]PRIVATE\WINCEOS\COREOS\NK\INC目錄的schedule.c、kernel.h的幾個檔案,其目的在於了解程式在開發執行時,對系統資源的共享以及程式的排程。
3.1處理程序的定義和描述
3.1.1處理程序概述
處理程序是一個具有一定獨立功能之程式的動態執行過程。
處理程序由正文段(text)、用戶資料段(usersegment)以及系統資料段(systemsegment)共同組成一個執行環境,負責處理器、記憶體和週邊等資源的分配和回收。
處理程序是電腦系統資源的使用主體,是作業系統分配資源的基本單位。
處理程序具有動態性、獨立性、並行性和結構化等特徵。
動態性是指處理程序具有動態的位址空間,位址空間的大小和內容都是動態變化的。
位址空間的內容包括程式碼(指令執行和處理器狀態的改變)、資料(變數的生成和初始化)和系統控制資訊(PCB(ProcessControlBlock)的生成和刪除)。
獨立性是指各個處理程序的位址空間相互獨立,除非採用處理程序間通信服務,否則不能相互影響。
並行性也稱為非同步性,是指從宏觀上來看,各個處理程序是同時獨立運行的。
結構化是指處理程序對於位址空間的結構劃分,如程式碼段、資料段和核心段劃分。
我們必須瞭解處理程序和程式的區別,程式是一個普通檔案,是一個程式碼指令和資料的集合,這些指令和程式碼儲存在磁片上成為可執行映射(ExecutableImage),是一個靜態的實體。
我們可以用下面簡單的方式了解處理程序和程式的關係:
1.處理程序和程式的關係
程式是處理程序的兩個重要組成之一。
處理程序的主要目的是執行它所對應的程式。
2.處理程序和程式的區別
主要有以下三種:
●程式是靜態的,處理程序是動態的;
●程式可以在儲存設備(如:
磁片)上長期保存,而處理程序則是在建立處理程序後產生,結束處理程序後消失。
●一個程式可以對應多個處理程序,但是一個處理程序只能對應一個程式。
例如:
打開Word的兩個視窗,編輯兩個不同的文字檔,就對應到兩個不同的處理程序。
3.1.2WindowsCE處理程序的描述
WindowsCE的處理程序不同於Windows98或WindowsNT,最大差別在於 WindowsCE最多只可以支援32個處理程序在系統中同時運行,系統啟動的時候,將至少自動啟動四個處理程序,一個是NK.exe,用來提供作業系統中kernel的服務,第二個是FILESYS.EXE,它用來提供相關檔案系統的服務,第三個是GWES.EXE,它用來提供對GUI系統的支援,第四個是DEVICE.EXE,它用來載入和管理週邊的驅動程式。
他們佔據虛擬位址的前四個slots,一個slot有32MB空間,詳見資料儲存部分的介紹,目前執行的處理程序將會對應到第一個slot(slot0)。
大部分的WindowsCE系統,也會同時建立EXEPLORER.EXE處理程序﹔如果WindowsCE系統正在與個人電腦相連,則會啟動REPLLOG.EXE和PAPISRV.EXE,他們用來管理個人電腦和WindowsCE系統之間的連接服務。
所以使用者可以啟動的處理程序最多大概有24個,或稍微多一點,但是對一般的使用來說,這是足夠的。
不同於Windows98或WindowsNT系統,WindowsCE系統不支援一些功能,例如WindowsCE系統不支援許多處理程序和與執行緒相關的函數。
WindowsCE系統不支援環境(environment),所有與處理環境有關的Win32函數在WindowsCE系統中並不存在。
3.1.3WindowsCE處理程序結構分析
在WindowsCE中,每一個處理程序由一個程序結構來描述。
也就是我們平時說的PCB。
它定義於NK/INC/kernel.h。
處理程序的所有資訊都保存在這個結構中,當系統建立一個處理程序時,將分配一個新的程序結構,處理程序結束時,這個結構將被回收。
與Windows98或WindowsNT的處理程序相比較,WindowsCE處理程序包含比較少的狀態資訊。
由於WindowsCE不支援驅動程式及工作目錄(WorkingDirectory)的概念,所以每個處理程序不需要保存這些資訊。
WindowsCE也不需要保存一系列的環境變數,所以PCB中不需要有關於環境變數的部分。
WindowsCE不支援控制碼繼承,所以也不需要告訴處理程序這些相關的資訊。
由於以上種種原因,WindowsCE處理程序的結構相對地簡單很多。
處理程序是系統資源分配的基本單位,為方便管理,在WindowsCE中把處理程序當作物件(HANDLEhProc)。
下面將簡單介紹一個程序結構的主要部分:
●procnum:
BYTE類別,目前處理程序的識別號碼(ID),用來辨識不同的處理程序。
●pProxList:
存放proxy的佇列,LPPROXY結構的鏈結。
●hProc:
這是此處理程序的控制碼,在呼叫SC_GetProcFromPtr時使用。
●dwVMBase:
DWORD類別,記錄處理程序在記憶體所占區域中的基底位址。
●pTh:
一個處理程序可能擁有多個執行緒(詳見執行緒介紹部分),pTh表示當前處理程序中的第一個執行緒。
●BasePtr:
LPVOID類別,指向載入.EXE可執行檔的基底指標。
●lpszProcName:
LPWSTR類別,記錄處理程序的名稱。
●PfnEH:
處理程序例外處理器,PEXCEPTION_ROUTINE類別。
●pMainTh:
此處理程序所擁有的主執行緒,當主執行緒結束後,處理程序也隨之結束。
●pmodResource:
PMODULE類別,MODULE結構在NK/INC/kernel.h中所定義。
包含資源的模組指標,其中的資源可以被目前的處理程序用到。
●oe:
openexe_t類別。
指向可執行檔控制碼的指標。
為了讓讀者容易理解,下面列出WindowsCE中所定義的程序結構。
程序的結構如下:
程式碼3.1
structProcess{
BYTEprocnum;/*00:
IDofthisprocess[ie:
it'sslotnumber]*/
BYTEDbgActive;/*01:
IDofprocesscurrentlyDebugActiveProcess'ingthisprocess*/
BYTEbChainDebug/*02:
Didthecreatorwanttodebugchildprocesses?
*/
BYTEbTrustLevel;/*03:
leveloftrustofthisexe*/
#defineOFFSET_TRUSTLVL3//offsetofthebTrustLevelmemberinProcessstructure
LPPROXYpProxList;/*04:
listofproxiestothreadsblockedonthisprocess*/
HANDLEhProc;/*08:
handleforthisprocess,neededonlyfor
SC_GetProcFromPtr*/
DWORDdwVMBase;/*0C:
baseofprocess'smemorysection,or0ifnotinuse*/
PTHREADpTh;/*10:
firstthreadinthisprocess*/
ACCESSKEYaky;/*14:
defaultaddressspacekeyforprocess'sthreads*/
LPVOIDBasePtr;/*18:
Basepointerofexeload*/
HANDLEhDbgrThrd;/*1C:
handleofthreaddebuggingthisprocess,ifany*/
LPWSTRlpszProcName;/*20:
nameofprocess*/
DWORDtlsLowUsed;/*24:
TLSinusebitmask(first32slots)*/
DWORDtlsHighUsed;/*28:
TLSinusebitmask(second32slots)*/
PEXCEPTION_ROUTINEpfnEH;/*2C:
processexceptionhandler*/
LPDBGPARAMZonePtr;/*30:
Debugzonepointer*/
PTHREADpMainTh;/*34primarythreadinthisprocess*/
PMODULEpmodResource;/*38:
modulethatcontainstheresources*/
LPNamepStdNames[3];/*3C:
Pointertonamesforstdio*/
LPCWSTRpcmdline;/*48:
Pointertocommandline*/
DWORDdwDyingThreads;/*4C:
numberofpendingdyingthreads*/
openexe_toe;/*50:
Pointertoexecutablefilehandle*/
e32_litee32;/*?
?
:
structurecontainingexeheader*/
o32_lite*o32_ptr;/*?
?
:
o32arraypointerforexe*/
LPVOIDpExtPdata;/*?
?
:
extendpdata*/
BYTEbPrio;/*?
?
:
highestpriorityofallthreadsoftheprocess*/
BYTEfNoDebug;/*?
?
:
thisprocesscannotbedebugged*/
WORDwPad;/*padding*/
};/*Process*/
3.1.4處理程序的同步與互斥
WindowsCE在NK\INC\schedule.h中定義了event(相當於觸發器,可以用於通知個別或多個執行緒某個event的出現)、mutex與semaphore三種同步物件。
而在NK\kernel.c中定義了這些同步物件的系統呼叫,可以用於處理程序或者執行緒的同步和互斥。
具體關於semaphore、mutex、event的機制不再介紹,這跟在Windows2000中的semaphore、mutex、event有一定的相同之處,讀者可以參考Windows2000中的對應結構以獲得更一步的瞭解,這裏只介紹相關的API函數。
1.event
event是同步物件之一,用於通知執行緒事件的發生,有signaled和nonsignaled兩種狀態。
建立時可以選擇自動從signaled狀態恢復到nonsignaled狀態,或者手動恢復。
從WindowsCE2.0開始,event可以被命名,因此可以被處理程序用於同步通信的共用。
與事件相關的API有:
SC_CreateEvent,用於建立一個event並傳回相應的控制碼﹔SC_OpenEvent,用於打開一個已經存在的event,並傳回相應的控制碼﹔SC_EventCloseHandle,用於關閉一個event等等。
下面以其中的部分函數為例,進行簡單的說明。
函數原型:
HANDLECreateEvent(
LPSECURITY_ATTRIBUTESlpEventAttributes,
BOOLbManualReset,
BOOLbInitialState,
LPTSTRlpName
);
要達到處理程序間的event共用,處理程序必需各自建立一個相同名字的event,而不能只在單一處理程序中建立,再把控制碼交給其餘處理程序使用。
要用它來發號誌,可以使用以下函數:
BOOLSetEvent(HANDLEhEvent);//只釋放一個等待的執行緒
BOOLPulseEvent(HANDLEhEvent);//釋放所有等待的執行緒//釋放所有等待的執行緒
BOOLResetEvent(HANDLEhEvent);//手動恢復nonsignal狀態//手動恢復nonsignal狀態
與mutex的API有:
SC_CreateMutex、SC_ReleaseMutex等等,分別用來建立和釋放一個mutex,這裏不再詳細說明,請讀者自己參閱Windows2000對應函數的說明。
與semaphore有關的API有:
SC_CreateSemaphore、SC_ReleaseSemaphore、SC_SemCloseHandle等等,分別用來建立semaphore,釋放semaphore,以及關閉一個semaphore的控制碼時使用,這裏也不詳細說明,請讀者參閱Windows2000對應函數的說明。
2.相關的等待函數
DWORDWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds);
作用:
執行緒等待一個event,用於停滯(Block)執行緒直到等待的event發出信號或者預定的時間到達。
其回傳值表明了等待結束的原因,回傳值可能如下:
WAIT_OBJECT_0//指定的event發出信號
WAIT_TIMEOUT//時間到,但等待的event沒有發出信號
WAIT_ABANDONED//被等待的執行緒結束了,但沒有釋放event
WAIT_FAILED//同步對象的控制碼不合法
DWORDWaitForMultipleObjects(DWORDnCount,CONSTHANDLE*lpHandles,BOOLbWaitAll,
DWORDdwMilliseconds);
作用:
執行緒等待多個event,WindowsCE不允許等待所有event發信號,所以bWaitAll只能為FALSE,當任何一個event發信號時,函數就返回。
其回傳值與前一函數基本相同,只是如果是event發出信號而返回時,回傳值為WAIT_OBJECT_0加上同時發出信號事件的控制碼(handle)中最小的註標(即lpHandles發出信號事件中最小的註標)。
3.2執行緒介紹
3.2.1執行緒概述
從60年代處理程序的概念提出以來,處理程序就一直是作業系統獨立運行的基本單位,在多個處理程序同時執行時,處理程序切換的系統負荷卻非常的大,在此同時,處理程序間資料共享的效率亦受到高度重視。
80年代中,人們提出了比處理程序更小、且能獨立運行的基本單位——執行緒(thread),目的是用來減少程式同時執行時所需要的事件和空間使用,提高處理程序的並行性。
1.執行緒的概念:
執行緒是處理程序的一個實體,是CPU排程和分配的基本單位,除了一些在運行中必要的資源(例如:
程式計數器,一些暫存器和堆疊),執行緒基本上不擁有系統資源,但是執行緒可以和同屬於同一個處理程序的其它執行緒共用處理程序所擁有的全部資源。
一個執行緒可以建立和撤銷另一個執行緒,同一個處理程序內的執行緒也可以並行執行。
執行緒具有處理程序所具有的許多特徵,所以又被稱為輕量級處理程序。
通常一個處理程序都有至少有一個以上的執行緒(WindowsCE中是主執行緒)。
下面將簡單地比較執行緒和處理程序的差別:
●排程方面:
傳統作業系統中,處理程序是分配資源,獨立排程和分派的基本單位。
引入執行緒後,執行緒是排程和分派的基本單位,處理程序仍然是擁有資源的基本單位。
將原本處理程序的兩個屬性分開(為資源分配與排程的基本單位),執行緒成為排程的基本單位後,執行緒就可以輕裝執行,這樣可以顯著提高系統的並行程度,同一處理程序內部執行緒的切換並不需要處理程序的切換。
●並行性:
引入執行緒,不僅在處理程序之間可以並行執行,而且在一個處理程序中的多個執行緒之間也可以並行執行,因此作業系統具有更好的並行性,並且能更有效的使用系統資源及提高系統的效率。
●資源之擁有:
處理程序是一個擁有資源的獨立單位,一般來說,執行緒不擁有自己的系統資源,它使用其所屬的處理程序的資源。
系統負荷:
由於處理程序的建立、結束或切換時,系統都要為處理程序分配、回收或暫存資源,付出的代價比較大,而執行緒的建立、結束及切換所需要和保存的資源(如:
暫存器)較少,所以執行緒之各項系統負荷遠遠小於處理程序所需。
2.引入執行緒的優點:
●建立一個新執行緒的負擔比建立處理程序少得多。
建立執行緒不需要額外分配大量資源,所以相對於建立處理程序,建立執行緒的速度要快得非常多,而且系統的負擔也非常小。
●兩個執行緒之間的切換時間非常的快。
●在同一個處理程序內的執行緒共用處理程序所擁有的資源(包括記憶體和檔案等),所以執行緒之間的資料共享不需要額外的機制﹔簡化的通訊方式,也使資料交換速度得以加快。
●執行緒能獨立執行,所以能充分利用和發揮處理器與週邊設備的並行工作能力。
3.2.2WindowsCE執行緒的結構分析
在WindowsCE中,每一個執行緒由一個在NK/INC/kernel.h中定義的thread結構所描述。
下面對執行緒的資料結構進行大致的分類:
1.wInfo資訊:
它是一個16位元的無符號整數(unsignedinteger),包括下列資訊(見表3.1):
表3.1wInfo資訊
名稱
說明
TIMEMODE_SHIFT
執行緒所處的時間模式
RUNSTATE_SHIFT
執行緒是否可執行
BURIED_SHIFT
隱藏偏移
SLEEPING_SHIFT
執行緒是否在睡眠
DEBUGBLK_SHIFT
是否啟動偵錯,暫停了執行緒
DYING_SHIFT
是否被設定為結束
STACKFAULT_SHIFT
堆疊錯誤資訊
DEAD_SHIF
執行緒有關結束的資訊
NEEDDBG_SHIFT
執行緒是否要偵錯
PROFILE_SHIFT
Montecarloprofiling
NOPRIOCALC_SHIFT
非優先順序計算位
DEBUGWAIT_SHIFT
執行緒偵錯等待資訊
USERBLOCK_SHIFT
執行緒是否可以自動進入停滯狀態
NEEDSLEEP_SHIFT
執行緒是否應該放回睡眠佇列中
我們可以透過在kernel.h中定義的偏移量來獲得以上的資訊:
#defineRUNSTATE_SHIFT0//2位(bit)
#defineDYING_SHIFT2//1位
#defineDEAD_SHIFT3//1位
#defineBURIED_SHIFT4//1位
#defineSLEEPING_SHIFT5//1位
#defineTIMEMODE_SHIFT6//1位
#defineNEEDDBG_SHIFT7//1位
#defineSTACKFAULT_SHIFT8//1位
#defineDEBUGBLK_SHIFT9//1位
#defineNOPRIOCALC_SHIFT10//1位
#defineDEBUGWAIT_SHIFT11//1位
#defineUSERBLOCK_SHIFT12//1位
#ifdefDEBUG
#defineDEBUG_LOOPCNT_SHIFT13//1位(僅在偵錯時使用)
#endif
#defineNEEDSLEEP_SHIFT14//1位
#definePROFILE_SHIFT15//1位,必須是15,透過組合語言來使用
2.各種鏈結資訊
一個執行緒屬於某個處理程序,一個處理程序中可能同時有多個執行緒,排程以執行緒為基本單位,某個執行緒可能正在執行,可能處於可執行佇列,也可能處於睡眠佇列,所以需要各種連結資訊來聯繫不同的執行緒,執行緒的一些主要連接資訊如表3.2所示:
表3.2執行緒的一些主要連接資訊
名稱
描述
PnextInProc
指向目前處理程序的下一個執行緒
Pproc
指向目前處理程序的指標
PprevInProc
目前處理程序的上一個執行緒
POwnerProc
指向父處理程序的指標
pNextSleepRun
下一個睡眠的執行緒,或者是下一個可執行的執行緒
pPrevSleepRun
上一個睡眠的或可執行的執行緒
pUpRun;
指向上一個執行緒,它執行完後自己才可以執行
pDownRun
指向等待此執行緒執行完後才可執行的執行緒
pUpSleep
指向上一個執行緒,它執行完後自己才被喚醒
pDownSleep
指向等待此執行緒執行完後才喚醒的執行緒
3.執行緒排程資訊
系統透過排程資訊來決定讓那一個執行緒運行,這主要由執行緒的目前優先順序(bCPrio)決定,而透過執行緒的時間片段(dwQuantum)資訊,系統可以決定讓執行緒執行多長的時間。
由於使用preemptiveround-robin排程演算法,所以一個正在執行的執行緒被preempted後,它所剩下的時間資訊也要保留。
表3.3執行緒資料結構中的一些排程相關資訊
名稱
含義
bBPrio
基本的優先順序
bCPrio
目前優先順序
dwQuantum
執行緒所擁有的時間片段
dwQuantLeft
執行緒所剩下的時間片段
4.執行緒時間資訊
執行緒從建立到結束間有一個生命週期,kernel需要記錄並統計執行緒所耗費的CPU時間。
這個時間分為user-mode時間和kernel-mode時間,每個時間中斷,kernel都要更新先前正在執行的執行緒所耗費的時間資訊。
除了這些,還有一些其他的相關資訊,表3.4中列出了一些比較重要的時間資訊:
表3.4執行緒時間資訊
名稱
描述
ftCreate
執行緒建立的時間
dwKernTime
執行緒在kernel-mode所消耗的時間
dwUserTime
執行緒在user-mode所消耗的時間
dwPendTime
執行緒等待操作的最長等待時間
dwPendWakeup
執行緒等待的最長時間
5
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程和线程 进程 线程
![提示](https://static.bdocx.com/images/bang_tan.gif)