函數說明
BOOL CloseHandle(HANDLE hObject);
參數
hObject :代表一個已打開對象handle。
返回值
TRUE:執行成功;
FALSE:執行失敗,可以調用GetLastError()獲知失敗原因。
函數用於關閉一個內核對象。
CloseHandle到底做了什麼?
當調用CloseHandle成功後,相關的內核對象的引用計數被減1。
這個函數做的工作就這麼多。它並沒有真正的關閉內核對象,只是將計數減1,也就是說,這個時候,如果這個內核對象的引用計數不爲0的話,內核對象依然存在,如果你有辦法找到他,那麼你依然可以操作他。
一個比較常見的問題:
CreateThread後立即CloseHandle,爲什麼線程還在運行?
可以這樣認爲,CreateThread之後,線程的內核對象的引用計數爲2,CloseHandle之後,如果線程還沒有結束,那麼他的引用計數是1,不是0,此時,系統不會回收內核對象,所以線程還在執行。直到線程執行結束,引用計數變成了0,此時,系統回收。
內核對象什麼時候被刪除?
以下兩種情況,內核對象會被刪除--系統回收:
- 當內核對象的引用計數爲0的時候
- 進程結束後
----摘自Windows核心編程 第四版 4.3.3
內核對象泄露
內核對象在使用完畢之後,沒有及時調用CloseHandle關閉,在該進程運行期間,將造成內核對象泄露。
內核對象泄露會對系統造成一定程度的負面影響,但進程結束退出後,操作系統會自動回收這些內核對象。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CloseHandle(hThread);
如上面這樣的代碼,原因爲:創建線程後返回了線程句柄,新創建的線程內核對象的使用計數是2,一個是線程本身,一個是創建線程的線程,創建線程的線程closehandle後,新的線程的內核對象使用計數爲1,當這個新線程結束運行後內核對象的使用計數還要減1,這時內核對象的使用計數是0,則系統會自動刪除新線程的內核對象,這是正常的處理流程。
如果不調用CloseHandle();則新線程運行結束後,由於使用計數爲1,所以不會刪除線程內核對象,這樣就會造成內存泄漏。當然在整個程序運行結束後,操作系統會回收這些內存,因此可以知道如果不調用CloseHandle()的話,在程序運行階段會造成內存泄漏!
本文參考:
《Windows核心編程 第四版》
http://blog.csdn.net/mvtechnology/article/details/72674524