進程PID、線程ID、實例Instance、句柄Handle的關係及App.hInstance 的用途

Q:《深入簡出MFC》p91下面有這麼一句話   
InitApplication和InitInstance現在成爲MFC的CWinApp的兩個虛函數,前者負責   
“每一個程序只做一次”的操作,後者負責“每一個例程都得做一次”的操作  

 

A:“每一個程序”指的是進程的概念。

“每一個例程”指的是線程的概念。   
 所以InitApplication負責“每一個程序只做一次”的操作。   
 而InitInstance是每一個線程都具有的函數,只不過很多情況下,你自己開的線程沒有重載該函數。

 

 

Q:請幫忙說明一下進程PID、線程ID、實例Instance、句柄Handle的關係及App.hInstance 的用途  
  
A:每個PE程序當被執行時,操作系統將爲它分配一塊內存,並將這個PE程序以及和它相關的動庫鏈接庫,一起壓棧,壓棧成功,則生成一個進程,並且爲這個進程分配一個唯一的ID號,我們稱這個是PID,就像門牌號碼一樣,你要找一個已經成功入住的房子,那麼你可以靠這個門牌號碼找到,當PE程序內部生成新的線程時,那麼在這個進程會向操作系統發出申請,此時操作系統會爲它分配此內存塊中的另一塊內存,此時的線程塊只是在主進程中另外分配出來的一塊,並沒有向操作系統申請進程外的內存塊,當房子造好後,這個房子裏面可以有很多空的房間,那麼一開始房間是空在那裏的,僅當有人入住時,這個房間纔會被開出來,道理是一樣的,PE中的代碼再有多的線程代碼,僅當線程代碼被執行時,進程纔會向操作系統提出申請,否則此線程將不被執行,這個線程ID就是房間的間號.如果要問PID和線ID之間 的聯繫的話,那麼可以一句話概括即:同一個進程中可以有N個線程,當進程生命週期結束時,它裏面不管有多少線程正在工作,都將被停止並回收資源.
Handle是個句柄,每個被成功生成的元都將會生成一個唯一的句柄(當然了有些特殊封裝技術生成的的元是沒有句柄的,這個我們這裏不討論),通過這個句柄我們可以準確的找到這個元,進行操作
App.hInstance返回操作系統爲此PE程序,分配的內存首地址,剛纔已經說過了,當PE要正常執行時,必須要被壓入內存,既然在內存中存在了,那麼它肯定有首地址和尾地址,通過這二個地址組成一個內存塊.
  
不管是進程還是線程,理論上面它們是各自獨立的,但並不是說不能被注入,有的進程爲什麼不能被注入,是因爲此PE代碼在系統底層對此內存塊進行了保護,使得我們在外表看出來好像不能被注入,線程也一樣,沒有不能被注入的內存塊,只是寫代碼的人技術有高低.

 

在WinDef.h有這麼一句:typedef HANDLE HINSTANCE;
數據上兩者是一樣的,本質上沒什麼區別。

HANDLE是用來標記資源的,也就是handle to an object。
HINSTANCE是Handle to an instance, 是HANDLE的一種特殊情況,常用來標記App實例。

 

 

Q:HINSTANCE指的是一個線程還是一個進程?

 

A:是“模塊”的實例,和線程和進程關係不大。

你的應用程序a.exe,可能需要b.dll的支持,那麼在程序運行的時候,a.exe這個進程裏面就包含了a.exe模塊和b.dll模塊,而他們的HINSTANCE其實就是每個模塊的進程首地址,也叫做基地址。

 

 

Q:winapi編程中instance是個什麼東西?

 

A:應用程序實例,
簡單的來說,就是用來標識你的應用程序的,windows是多任務操作系統,同時有很多應用程序在運行,需要標識出每個應用程序。
同樣,每個應用程序又會有多個窗口,那麼每個窗口都有窗口句柄來標識是哪個窗口。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章