1. 程式人生 > 實用技巧 >windows-程序執行緒

windows-程序執行緒

程序執行緒

windows系統

windows是C和彙編寫的,但是是採用的面向物件的思想寫的,一個一個windows的物件本質上都是結構體變數,但是windows並不想直接暴露結構體,於是windows採用了控制代碼來封裝一層對應的結構體,然後再用控制代碼對應的API來操作這些物件

在windows下分為R0核心區和R3使用者區,核心區就是各種各樣的windows物件(結構體),然後封裝藉口函式再封裝到R3變成sdk,api等等給R3的User使用。

windows物件

可以大致分為三類

USER物件:視窗,控制元件、圖示、選單、游標 User32.dll中

GDI物件:畫刷,字型,畫筆 GDI32.dll中

核心物件:檔案、程序、執行緒。 Kernel32.dll中

核心物件的建立方式

1 建立物件CreateXXXX

例:CreateProcess 建立程序 CreateThread建立執行緒,CreateFile建立檔案,CreateSemaphore建立訊號量等

2 開啟物件獲取控制代碼 OpenXXX

3 通過API來操作物件 前兩步都是為了第三步用API來操作核心物件

4 關閉控制代碼

核心物件特性:

所有的核心物件都屬於作業系統核心,可以再不同的程序間訪問到,也就是說核心物件是跨程序的。

很多時候都需要在不同的程序中訪問同一個核心物件,比如:程序的同步,程序共享資料等

通常,使用命名的方式在不同程序間使用核心物件

引用計數

每個核心物件都有一個引用計數,也就是說每個核心物件都有個變數來計數,統計有幾個程序建立或打開了此核心物件,如果有建立和開啟,該計數加一,如果某個程序終止,或者關閉了這個物件,那麼計數量減1,當計數為0的時候就會銷燬

安全描述符

核心物件都有一個安全描述符,這個描述符說明了誰擁有此物件,哪些使用者和組被允許訪問或使用此物件,以及哪些使用者和組拒絕訪問或使用此物件。

在建立一個核心物件的同時,需要我們傳遞一個安全描述符

可以通過傳參是否傳安全描述符來判斷是否為核心物件

typedef struct _SECURITY_ATTRIBUTES { DWORD nLength;//結構體大小 LPVOID lpSecurityDescriptor;//安全描述符 BOOL bInheritHandle;//是否能被新建立的程序繼承 } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;

一般情況下,在建立核心物件的時候給安全描述符傳NULL,就表示使用預設安全屬性

windows中使用物件就要使用控制代碼

對於核心物件來說,核心物件的控制代碼和程序相關,同一個物件不同的程序中的物件控制代碼不同,但是需要注意的是GID物件的控制代碼值是全域性有效的

控制代碼表

每個程序物件中,都有一個控制代碼表,用來記錄該程序開啟的所有核心物件

可以簡單的認為控制代碼表就是一個一維陣列,控制代碼值表示的是一個數組的索引值

控制代碼表中的每一項描述了使用此控制代碼訪問物件的許可權和是否可以被子程序繼承

核心物件的跨程序訪問

核心物件是全域性的,所有可以在多個程序中來訪問核心物件

通常有3中方式實現跨程序訪問核心物件

1 父程序繼承給子程序

2 使用名稱或者ID作為標識來開啟

3 使用DuplicateHandle函式,將控制代碼從一個程序傳遞給另一個程序

win10下的32位應用程式

作業系統會分配一個程序來處理該應用程式,該程序因為是32位的所以作業系統會給它分配一個4G的記憶體,該記憶體會分為兩塊,低2G的記憶體是使用者空間,而高2G的記憶體是核心空間。低兩G是使用者程序的私有空間,而高2G則是核心空間,核心物件的特質就是所有程序共享,所以這裡的空間是共享的。

什麼是程序

程序是作業系統的一個重要概念,執行一個程式就會執行一個程序,程序是作業系統用來分配資源的單位。類似於一個工廠,工廠裡的員工就類似於執行緒來處理工作

至少包含:

虛擬地址空間(也就是低2G的使用者空間)

地址空間中載入的exe,還有dll

程序核心物件(在核心層中)

至少一個執行緒

什麼是模組

包含著程式碼和資料的可執行檔案稱之為可執行檔案

windows下最常見的:exe、dll檔案

一個執行中的程序通常都要將好幾個可執行檔案載入到記憶體虛擬空間,每個在該程序中載入的可執行檔案都稱之為模組

程式碼實操

#include<Windows.h>

int main()
{
/*
BOOL CreateProcessA(
LPCSTR lpApplicationName, 程式路徑
LPSTR lpCommandLine, 要執行的命令,如果是NULL就是表示執行命令列
LPSECURITY_ATTRIBUTES lpProcessAttributes,程序安全描述符
LPSECURITY_ATTRIBUTES lpThreadAttributes, 執行緒安全描述符
BOOL bInheritHandles, 是否可被繼承
DWORD dwCreationFlags, 建立標識
LPVOID lpEnvironment, 指向新程序環境塊指標通常為NULL
LPCSTR lpCurrentDirectory, 程序當前目錄的完整路徑,前面給了完整路徑的畫通常為NULL
LPSTARTUPINFOA lpStartupInfo, 程序啟動資訊
LPPROCESS_INFORMATION lpProcessInformation 程序資訊
//除了程序啟動資訊和程序資訊還有程式路徑,別的基本上用預設值就好

);
*/
//這裡啟動路徑用我寫的MFC試試
LPCSTR a ="D:\\Summer\\CC++\\MFC\\MFC_LIST\\Debug\\MFC_LIST.exe";
STARTUPINFOA sw{ 0 };
PROCESS_INFORMATION pinfo{ 0 };
//在windows下的lp表示的是long point也就是指標型別的意思
CreateProcessA(a,NULL,NULL,NULL,FALSE,0,NULL,NULL,&sw,&pinfo);
CloseHandle(pinfo.hThread);
CloseHandle(pinfo.hProcess);
return 0;


}

這個程式的意思就是,啟動一個程序用來執行a位置的應用程式