轉載地址:https://blog.csdn.net/qq_38499859/article/details/80057427
一.目錄
文章目錄
操作系統3 ————進程控制塊(PCB)詳解
一.目錄
二. 進程控制塊
1.概述
2.進程控制塊中的信息
3.進程控制塊的作用
4.進程控制塊的組織方式
三.Linux的進程控制塊
1.概述
2.task_struct數據結構簡述
四.Unix的進程控制塊
1.概述
2.進程表項(Proc表)
3.U區
4.系統區表
5.進程區表
五.windows的進程控制塊
1.概述
2.EPROCESS的數據結構
六.參考資料
二. 進程控制塊

1.概述
學生檔案是對每個學生的描述,其中含有學生的姓名學號年齡年級班級等信息,那么操作系統對進程的描述是什么,其中又包含哪些信息?
進程信息被放在一個叫做進程控制塊的數據結構中。 進程控制塊(PCB:Processing Control Block),是操作系統核心中一種數據結構,主要表示進程狀態,其作用是使一個程序成為一個能夠獨立運行的基本單位,並且可以並發執行的進程。或者說,OS是根據PCB來對並發執行的進程進行控制和管理。PCB通常是占用系統內存中一塊連續的內存空間,存放着操作系統用於描述進程情況及控制進程運行的全部信息。
是操作系統中最重要的記錄型數據結構,Linux 系統中用 task_struct 數據結構表示PCB,Windows:執行體進程塊(EPROCESS)表示PCB。
在進程創建狀態的時候創建pcb、在進程終止的時候銷毀pcb
2.進程控制塊中的信息
a.進程標識符(PID:Process Identifier)。
內部標識符SID:操作系統為每一個進程賦予的唯一數字標識符,系統使用
外部標識符:由創建者提供,通常有字母與數字組成,往往是由用戶(進程)在訪問該進程時使用。描述進程的家族關系,設置父進程標識及子進程標識,還可設置用戶標識,以指示擁有該進程的用戶。
b.上下文數據
主要是由處理機的各種寄存器中的內容組成的,處理機被中斷時,所有這些信息都必須保存在PCB中,以便在該進程重新執行時,能從斷點繼續執行。
這些寄存器包括: 通用寄存器、指令計數器、程序狀態字PSW、用戶棧指針
c.進程調度信息
進程狀態:創建、就緒、阻塞、執行、終止
進程優先級:進程有6個優先級類
進程調度所需要的其他信息,比如已等待CPU的時間綜合,進程一直想的時間總和。
事件,指進程由執行狀態轉變為阻塞狀態所等待發生的事件,即阻塞原因
d.進程控制信息
程序和數據的地址
進程同步和通信機制
資源清單
鏈接指針
I/O狀態信息
包括顯示的I/O請求,分配給進程的I/O設備和被進程使用的文件列表。
3.進程控制塊的作用
PCB 可以被操作系統中的多個模塊讀或修改,如被調度程序、資源分配 程序、中斷處理程序以及監督和分析程序等讀或修改。 OS是根據 PCB來對 並發執行的進程進行控制和管理,所以說PCB是操作系統中最重要的記錄型數據結構
其作主要作用如下:
1、作為獨立運行基本單位的標志
2、能實現間斷性運行方式
3、提供進程管理所需要的信息
4、提供進程調度所需要的信息
5、實現與其他進程的同步與通信
4.進程控制塊的組織方式
a.線性方式: 即將系統中所有的PCB都組長在一張線性表中,將該表的首地址存放在內存的一個專用區域中。適合於系統中進程數目不多的情況
**b.鏈接方式:**該方式是線性表方式的改進,系統按照進程的狀態分別建立就緒索引表、阻塞索引表等。
**c.索引方式:**系統按照進程的狀態將進程的PCB組成隊列,從而形成就緒隊列、阻塞隊列、運行隊列等。
三.windows的進程控制塊
概述
在windows中執進程控制塊是由 EPROCESS 塊來表示的。 EPROCESS 塊位於內核層之上,它側重於提供各種管理策略,同時為上層應用程序提供基本的功能接口。所以,在執行體層的進程和線程數據結構中,有些成員直接對應於上層應用程序中所看到的功能實體。
EPROCESS結構屬於內核的執行體層,包含了進程的資源相關信息諸如句柄表、虛擬內存、安全、調試、異常、創建信息、I/O轉移統計以及進程計時等。
EPROCESS的數據結構
typedef struct _EPROCESS { KPROCESS Pcb; //KPROCESS被內核用來進行線程調度使用 EX_PUSH_LOCK ProcessLock;//ProcessLock域是一個推鎖(push lock)對象,用於保護EPROCESS中的數據成員。用來對可能產生的並行事件強制串行化。 LARGE_INTEGER CreateTime; //這兩個域分別代表了進程的創建時間和退出時間 LARGE_INTEGER ExitTime; EX_RUNDOWN_REF RundownProtect; //RundownProtect域是進程的停止保護鎖,當一個進程到最后被銷毀時,它要等到所有其他進程和線程已經釋放了此鎖,才可以繼續進行,否則就會產生孤兒線程 HANDLE UniqueProcessId; //UniqueProcessId域是進程的唯一編號,在進程創建時就設定好了,我們在"任務管理器"中看到的PID就是從這個域中獲取的值 LIST_ENTRY ActiveProcessLinks; //ActiveProcessLinks域是一個雙鏈表節點(注意是雙鏈表中的一個節點),在windows系統中,所有的活動進程都連接在一起,構成了一個鏈表。 SIZE_T QuotaUsage[PsQuotaTypes];//QuotaUsage和QuotaPeak域是指一個進程的內存使用量和尖峰使用量 SIZE_T QuotaPeak[PsQuotaTypes]; SIZE_T CommitCharge; //CommitCharge域中存儲了一個進程的虛擬內存已提交的"頁面數量" SIZE_T PeakVirtualSize;//PeakVirtualSize域是指虛擬內存大小的尖峰值。 SIZE_T VirtualSize;//VirtualSize域是指一個進程的虛擬內存大小。 LIST_ENTRY SessionProcessLinks;//SessionProcessLinks域是一個雙鏈表節點,當進程加入到一個系統會話中時,這個進程的SessionProcessLinks域將作為一個節點(LIST_ENTRY在內核中很常見)加入到該會話的進程鏈表中。 PVOID DebugPort; //DebugPort和ExceptionPort域是兩個句柄(指針),分別指向當前進程對應的調試端口和異常端口。 PVOID ExceptionPort; PHANDLE_TABLE ObjectTable; //ObjectTable域是當前進程的句柄表。 EX_FAST_REF Token; //Token域是一個快速引用,指向該進程的訪問令牌,用於該進程的安全訪問檢查。 PFN_NUMBER WorkingSetPage; //WorkingSetPage域是指包含進程工作集的頁面 KGUARDED_MUTEX AddressCreationLock;//AddressCreationLock域是一個守護互斥體鎖(guard mutex),用於保護對地址空間的操作。 KSPIN_LOCK HyperSpaceLock;//HyperSpaceLock是一個自旋鎖,用於保護進程的超空間 struct _ETHREAD *ForkInProgress;//ForkInProgress指向正在復制地址空間的那個線程,僅當在地址空間復制過程中,此域才會被賦值,在其他情況下為NULL。 ULONG_PTR HardwareTrigger;//HardwareTrigger用於記錄硬件錯誤性能分析次數 PMM_AVL_TABLE PhysicalVadRoot;//PhysicalVadRoot域指向進程的物理VAD的根。它並不總是存在,只有當確實需要映射物理內存時才會被創建。 PVOID CloneRoot;//CloneRoot指向一個平衡樹的根,當進程地址空間復制時,此樹被創建,創建出來后,一直到進程退出的時候才被銷毀。CloneRoot域完全是為了支持fork語義而引入。 PFN_NUMBER NumberOfPrivatePages;//指進程私有頁面的數量 PFN_NUMBER NumberOfLockedPages;//指進程被鎖住的頁面的數量 PVOID Win32Process;//Win32Process域是一個指針,指向由windows子系統管理的進程區域,如果此值不為NULL,說明這是一個windows子系統進程(GUI進程) struct _EJOB *Job;//對於job域,只有當一個進程屬於一個job(作業)的時候,它才會指向一個_EJOB對象。 PVOID SectionObject;//SectionObject域也是一個指針,代表進程的內存去對象(進程的可執行映像文件的內存區對象) PVOID SectionBaseAddress;// SectionBaseAddress域為該內存區對象的基地址 PEPROCESS_QUOTA_BLOCK QuotaBlock;//QuotaBlock域指向進程的配額塊,進程的配額塊類型為: EPROCESS_QUOTA_BLOCK PPAGEFAULT_HISTORY WorkingSetWatch;//WorkingSetWatch域用於監視一個進程的頁面錯誤,一旦啟用了頁面錯誤監視功能(由全局變量PsWatchEnabled開關來控制),則每次發生頁面錯誤都會將該頁面錯誤記錄到WorkingSetWatch域的WatchInfo成員數組中,知道數組滿為止。 HANDLE Win32WindowStation;//Win32WindowStation域是一個進程所屬的窗口站的句柄。由於句柄的值是由每個進程的句柄表來決定的,所以,兩個進程即使同屬於一個窗口站,它們的Win32WindowStation也可能不同,但指向的窗口站對象是相同的。窗口站是由windows子系統來管理和控制的。 HANDLE InheritedFromUniqueProcessId;//InheritedFromUniqueProcessId域說明了一個進程是從哪里繼承來的,即父進程的標識符。 PVOID LdtInformation;//LdtInformation用來維護一個進程的LDT(局部描述符表)信息。 PVOID VadFreeHint;//VadFreeHint域指向一個提示VAD(虛擬地址描述符)節點,用於加速在VAD樹中執行查找操作。 PVOID VdmObjects;//VdmObjects域指向當前進程的VDM數據區,其類型為VMD_PROCESS_OBJECTS,進程可通過NtVdmControl系統服務來初始化VDM。 PVOID DeviceMap;//DeviceMap域指向進程使用的設備表,通常情況下同一個會話中的進程共享同樣的設備表。 PVOID Spare0[3];//Spare0域是一個備用域 union //頁表項 { HARDWARE_PTE PageDirectoryPte; ULONGLONG Filler; }; PVOID Session;//Session指向進程所在的系統會話,實際上它是一個指向MM_SESSION_SPACE的指針。\base\ntos\mm\mi.h 中相關的結構體定義 UCHAR ImageFileName[ 16 ];//ImageFileName域包含了進程的映像文件名,僅包含最后一個路徑分隔符之后的字符串,不超過16字節。 LIST_ENTRY JobLinks;//JobLinks域是一個雙鏈表節點,通過此節點,一個job中的所有進程構成了一個鏈表。在windows中,所有的job構成了一個雙鏈表,其鏈表頭為全局變量PspJobList。每個job中的進程又構成了一個雙鏈表。 PVOID LockedPagesList;//LockedPagesList域是一個指向LOCK_HEADER結構的指針,該結構包含了一個鏈表頭,windows通過此鏈表來記錄哪些頁面已被鎖住(這里所謂的鎖住和Mdll中的映射機制有關,本質上就是把用戶空間下的內存地址鎖定到內核空間中以便訪問) LIST_ENTRY ThreadListHead; //ThreadListHead域是一個雙鏈表的"頭結點",該鏈表中包含了一個進程中的所有"線程"。 PVOID SecurityPort; //SecurityPort域是一個安全端口,指向該進程域lsass.exe進程之間的跨進程通信端口。 PVOID PaeTop; //PaeTop域用於支持PAE內存訪問機制。 ULONG ActiveThreads;//ActiveThreads域記錄了當前進程有多少活動線程。當該值減為0時,所有的線程將退出,於是進程也退出。 ACCESS_MASK GrantedAccess;//GrantedAccess域包含了進程的訪問權限,訪問權限是一個"位組合"。 public\sdk\inc\ntpsapi.h 中的宏 PROCESS_XXX ULONG DefaultHardErrorProcessing;//DefaultHardErrorProcessing域指定了默認的硬件錯誤處理,默認為1 NTSTATUS LastThreadExitStatus; //LastThreadExitStatus域記錄了剛才最后一個線程的退出狀態。 PPEB Peb; //Peb域是一個進程的"進程環境塊 EX_FAST_REF PrefetchTrace;//PrefetchTrace域是一個快速引用,指向與該進程關聯的一個"預取痕跡結構",以支持該進程的預取。 LARGE_INTEGER ReadOperationCount;//ReadOperationCount,WriteOperationCount記錄了當前進程NtReadFile和NtWriteFile系統服務被調用的次數,OtherOperationCount記錄了除讀寫操作以外的其他IO服務的次數(文件信息設置.) LARGE_INTEGER WriteOperationCount; LARGE_INTEGER OtherOperationCount; LARGE_INTEGER ReadTransferCount;//ReadTransferCount,WriteTransferCount記錄了IO讀寫操作"完成"的次數,OtherTransferCount記錄了除讀寫操作以外操作完成的次數。 LARGE_INTEGER WriteTransferCount; LARGE_INTEGER OtherTransferCount; SIZE_T CommitChargeLimit; SIZE_T CommitChargePeak; PVOID AweInfo; //AweInfo域是一個指向AWEINFO結構的指針,其目的是支持AWE(Adress Windowing Extension 地址窗口擴展) SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo;//SeAuditProcessCreationInfo域包含了創建進程時指定的進程映像全路徑名 MMSUPPORT Vm;//Vm域是windows為每個進程管理虛擬內存的重要數據結構成員,其類型為MMSUPPORT, \base\ntos\inc\ps.h 中有相關定義 LIST_ENTRY MmProcessLinks; //MmProcessLinks域代表一個雙鏈表節點,所有擁有自己地址空間的進程都將加入到一個雙鏈表中,鏈表頭是全局變量MmProcessList ULONG ModifiedPageCount; //ModifiedPageCount域記錄了該進程中已修改的頁面的數量,即"臟頁面數量",這和緩存的讀寫有關。 ULONG JobStatus; //49. ULONG JobStatus JobStatus域記錄了進程所屬job的狀態。 union //Flags域包含了進程的標志位,這些標志位反映了進程的當前狀態和配置。 \base\ntos\inc\ps.h 中的宏定義 PS_PROCESS_FLAGS_XXX { ULONG Flags; struct { ULONG CreateReported : 1; ULONG NoDebugInherit : 1; ULONG ProcessExiting : 1; ULONG ProcessDelete : 1; ULONG Wow64SplitPages : 1; ULONG VmDeleted : 1; ULONG OutswapEnabled : 1; ULONG Outswapped : 1; ULONG ForkFailed : 1; ULONG Wow64VaSpace4Gb : 1; ULONG AddressSpaceInitialized : 2; ULONG SetTimerResolution : 1; ULONG BreakOnTermination : 1; ULONG SessionCreationUnderway : 1; ULONG WriteWatch : 1; ULONG ProcessInSession : 1; ULONG OverrideAddressSpace : 1; ULONG HasAddressSpace : 1; ULONG LaunchPrefetched : 1; ULONG InjectInpageErrors : 1; ULONG VmTopDown : 1; ULONG ImageNotifyDone : 1; ULONG PdeUpdateNeeded : 1; // NT32 only ULONG VdmAllowed : 1; ULONG SmapAllowed : 1; ULONG CreateFailed : 1; ULONG DefaultIoPriority : 3; ULONG Spare1 : 1; ULONG Spare2 : 1; }; }; NTSTATUS ExitStatus;//ExitStatus域包含了進程的退出狀態,從進程的退出狀態通常可以獲知進程非正常退出的大致原因。反映退出狀態的一些宏定義位於 public\sdk\inc\ntstatus.h USHORT NextPageColor;//NextPageColor域用於物理頁面分配算法。 union { struct { UCHAR SubSystemMinorVersion; UCHAR SubSystemMajorVersion; }; USHORT SubSystemVersion; }; UCHAR PriorityClass;//PriorityClass域是一個單字節值,它說明了一個進程的優先級程度 MM_AVL_TABLE VadRoot;//VadRoot域指向一個平衡二叉樹的根,用於管理該進程的虛擬地址空間。 ULONG Cookie;//Cookie域存放的是一個代表該進程的隨機值,當第一次通過NtQueryInformationProcess函數獲取此Cookie值的時候,系統會生成一個隨機值,以后就用此值代表此進程 } EPROCESS, *PEPROCESS;
EPROCESS的數據解析
nt!_EPROCESS
Windows內核使用ERPROCESS結構體來表示一個進程,其包含了所有內核需要去保存關乎該進程的信息。對每一個運行在系統中的進程包括System Process和System Idle Process來說,都有一個對應的EPROCESS結構,System Process和System Idle Process運行在內核中。
EPROCESS結構屬於內核的執行體層,包含了進程的資源相關信息諸如句柄表、虛擬內存、安全、調試、異常、創建信息、I/O轉移統計以及進程計時等。
指向System Process的EPROCESS結構的指針保存在nt!PsInitialSystemProcess,而System Idle Process的EPROCESS指針保存在nt!PsIdleProcess。
任何進程都可以同時隸屬於多個集合或組。例如,一個進程總是在系統中active進程列表中,一個進程可以屬於內部運行着一個會話的進程集合,一個進程也可以是某個job的一部分。為了實現這些集合或組,EPROCESS結構通過不同的字段持有數個列表項。
ActiveProcessLink字段用於將該EPROCESS結構鏈入系統中active進程鏈表,該鏈表的頭保存在內核變量中nt!PsActiveProcessHead。類似的,SessionProcessLinks字段用於將該EPROCESS結構鏈入到一個會話鏈表,鏈表頭在MM_SESSION_SPACE.ProcessList。JobLinks字段用於將該EPROCESS結構鏈入到所屬的job鏈表中,鏈表頭在EJOB.ProcessListHead。內存管理器全局變量MmProcessList通過MmProcessLinks字段鏈入了一個進程鏈表。該鏈表可以通過MiReplicatePteChange()橫貫以更新內核模式中關於進程虛擬地址空間的那部分。
屬於進程的所有線程鏈表保存在ThreadListHead中,線程通過ETHREAD.ThreadListEntry排隊。
內核變量ExpTimerResolutionListHead持有一個進程鏈表,使用NtSetTimerResolution()來改變定時器間隔。該鏈表被ExpUpdateTimerResolution()函數使用來更新時間分辨率到所有進程需求值中最小的那個。
!process命令從EPROCESS結構展示信息。.process命令切換調試器的虛擬地址空間上下文到特定的進程,當在一個完全的內核轉儲中或現場使用內核調試器時進行用戶模式虛擬地址的實驗時,這是一個非常危險的操作。
