Windows內核之進程的終止和子進程
1 進程終止的方法:
<1>主線程的進入點函數返回(最好使用這種方法)
<2>進程中的一個線程調用ExitProcesss函數(應該避免使用這樣的方法)。
<3>還有一個進程中的線程調用TerminateProcess函數(應該避免使用這樣的方法)。
<4>進程中的全部線程自行終止執行(這樣的情況差點兒從未發生)。
1.1 主線程進入點函數返回
始終都應該這樣來設計應用程序。即僅僅有當主線程的進入點函數返回時,它的進程才終止執行。這是保證全部線程資源可以得到正確清除的唯一辦法。
<1> C++對象將可以使用它們的析構函數得以釋放
<2> 操作系統可以正確的釋放該線程使用的堆棧內存
<3> 系統將進程的退出代碼設置為進入點函數的返回值
<4> 系統將內核對象的計數值減去1
1.2 調用ExitProcess函數
voidExitProcess(uExitCode)
跟主線程的進入點函數返回相比,它就不那麽安全,不能保證資源被清理。
通過調用ExitProcess函數。C++/C執行期啟動代碼可以確保主線程從它的進入點函數返回時,進程便終止執行,而無論進程中是否還有其它線程在執行。
假設在進入點函數中調用ExitThread。那麽主線程就會停止執行,可是假設進程中假設還有其它線程的話。進程便不會終止。
ExitProcess以及ExitThread能保證操作系統資源在函數調用時被清除,可是不能保證C/C++執行時資源被正確的清除。所以不妨不要調用這些資源。
在前面也介紹過當主線程的進入點函數返回的時候。C/C++執行時會調用執行時的exit函數。exit函數會完畢以下操作
<1>調用_onexit函數的調用而註冊的人不論什麽函數
<2>為全部的全局和靜態的C++對象調用析構函數
<3>調用系統的ExitProcess函數。將nMainRetVal傳遞給它。
使得操作系統可以撤銷進程並設置它的exit代碼。
1.3 調用TerminateProcess 函數
BOOL TerminateProcess(HANDLE hProcess,UINTnExitCode)
這個函數通知進程內全部線程終止。當全部線程終止時。進程也會終止了,可是它不會告訴進程內相關聯的DLL這個進程將要被終止。它做的事情:
<1>全部打開的句柄被關閉
<2>全部的線程會被終止
<3>進程對象的狀態變為終止的,滿足全部等待進程結束的線程
<4>進程中全部線程對象的狀態變為終止。滿足全部等待線程結束的線程
<5>進程的終止狀態由STILL_ACTIVE變為了進程的返回代碼
這個函數是異步的。它告訴操作系統,你要終止某個進程。可是當函數返回的時候,你無法保證進程是否已經被殺死。假設想要確切知道進程是否被殺死,能夠使用WaitForSingleObject函數。
2 進程終止時的情況
<1>進程中全部剩余線程將被終止
<2>進程中指定的用戶對象,GDI對象被釋放。內核對象被關閉
<3>內核對象的狀態編程收到通知的狀態
<4>進程的退出代碼由STILL_ACTIVE 變為ExitProcess或者TerminateProcess傳遞的的退出代碼
<5>進程內核對象計數減去1
能夠通過函數 BOOLGetExitCodeProcess(HANDLE handle,LPDWORD lpExitCode)來查找進程的退出代碼。假設代碼是STILL_ACTIVE表示的是進程還沒終止。假設不是這個,就說明進程已經被終止。
3 子進程
程序中要實現一段功能一共同擁有3種方法:
<1>調用函數
<2>開辟新線程
<3>開辟新進程
3.1 調用函數
調用函數時很常見的。可是它的缺點是由於在同一個線程中,所以必須等待此函數運行完成,才幹運行後面的代碼
3.2 開辟新線程
這樣可以在新線程運行的時候,同一時候運行其它線程的代碼,可是這種缺點是不同線程之間須要交流數據時候。會產生同步的問題。
3.3 開辟子進程
這樣有點是既能夠保護數據。能夠同步運行,也能夠等待新進程運行完成再去運行其它進程的代碼。缺點是開辟新進程,會造成地址空間的浪費。
Windows內核之進程的終止和子進程