CreateThread()之後又馬上CloseHandle()的問題

很多程序在創建線程都這樣寫的:
............
ThreadHandle = CreateThread(NULL,0,.....);
CloseHandel(ThreadHandle );
。。。。。
這不是剛好創建又關閉了嗎?線程怎麼運行呢?

================================================

Closing a thread handle does not terminate the associated thread. To remove a thread object, you must terminate the thread, then close all handles to the thread.

================================================

1,線程和線程句柄(Handle)不是一個東西,線程是在cpu上運行的.....(說不清楚了),線程句柄是一個內核對象。我們可以通過句柄來操作線程,但是線程的生命週期和線程句柄的生命週期不一樣的。線程的生命週期就是線程函數從開始執行到return,線程句柄的生命週期是從CreateThread返回到你CloseHandle()。

2,所有的內核對象(包括線程Handle)都是系統資源,用了要還的,也就是說用完後一定要closehandle關閉之,如果不這麼做,你係統的句柄資源很快就用光了。

3,如果你CreateThread以後需要對這個線程做一些操作,比如改變優先級,被其他線程等待,強制TermateThread等,就要保存這個句柄,使用完了在CloseHandle。如果你開了一個線程,而不需要對它進行如何幹預,CreateThread後直接CloseHandle就行了。

所以
CloseHandel(ThreadHandle );
只是關閉了一個線程句柄對象,表示我不再使用該句柄,即不對這個句柄對應的線程做任何干預了。並沒有結束線程。

如果你覺得多了一個變量,也可以寫爲:
CloseHandel(CreateThread(NULL,0,.....));

================================================================

《windows核心編程》上說調用closehandle(HANDLE)表示創建者放棄對該內核對象的操作。如果該對象的引用對象記數爲0就撤消該對象。

====================================================================

在線程創建後馬上調用CloseHandle()是個良好的做法,這裏不會影響線程的執行,就是因爲即使你close了這個handle,它的內部記數也不爲零.   但如果你不關,在線程結束後,那個線程對象將滯留於內存中,也就是說你有handle   leak.
返回這個handle給你,是讓你有機會對這個線程實施外部動作,諸如waitforsingleobject之類.

==================================================================

CloseHandle的功能是關閉一個打開的對象句柄,該對象句柄可以是線程句柄,也可以是進程、信號量等其他內核對象的句柄,而ExitThread的功能是終止一個線程,它所接受的參數是一個線程的退出碼。
通過調用CloseHandle可以告知系統,已經完成了對某一內核對象的操作,該函數首先檢查調用進程的句柄表,來確認進程是否對該句柄所指向的對象有訪問權,如果句柄無效則返回FALSE,如果有效,系統將得到該內核對象的數據結構的地址,把結構中的使用計數成員減1,如果計數變爲0,則將從內核中釋放該內核對象。
如果計數還未到0,就意味着還有其他的進程在使用這個內核對象,那麼它就不會被釋放。
ExitThread是推薦使用的結束一個線程的方法,當調用該函數時,當前線程的棧被釋放,然後線程終止,相對於TerminateThread函數來說,這樣做能夠更好地完成附加在該線程上的DLL的清除工作。
如果需要進一步的信息,您可以參看:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/handobj_289x.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/prothred_531g.asp
等有關的MSDN信息。

==================================================================

線程作爲一種資源創建後不只被創建線程引用,我想系統自身爲了管理線程也會有一個引用,所以用戶線程釋放線程句柄後,引用計數也不會是零。引用計數是資源自我管理的一種機制,資源本身以引用計數爲零來得知別人不再需要自己,從而把自己kill掉。

=================================================================

CreateThread後那個線程的引用計數不是1,調用CloseHandle只是說自己對這個線程沒有興趣了,線程還是正常運行的

=================================================================

CreateThread後那個線程的引用計數不是1,而是2。
creating   a   new   process   causes   the   system   to   create   a   process   kernel   object   
and   a   thread   kernel   object.   At   creation   time,   the   system   gives   each   object   
an   initial   usage   count   of   1.   Then,   just   before   CreateProcess   returns,   the   
function   opens   the   process   object   and   the   thread   object   and   places   the   
process-relative   handles   for   each   in   the   hProcess   and   hThread   members   of   
the   PROCESS_INFORMATION   structure.   When   CreateProcess   opens   these   objects   
internally,   the   usage   count   for   each   becomes   2.

=================================================================

創建新的進程後,記數初始化爲1,而函數需要返回進程內核對象的句柄,相當於打開一次新創建的類覈對象,記數再加1

------------------------------------

CloseHandle函數

BOOL CloseHandle(

HANDLE hObject

);

參數

hObject :代表一個已打開對象handle。

返回值

TRUE:執行成功;

FALSE:執行失敗,可以調用GetLastError()獲知失敗原因。

函數說明:

關閉一個內核對象。其中包括文件、文件映射、進程、線程、安全和同步對象等。在CreateThread成功之後會返回一個hThread的handle,且內核對象的計數加1,CloseHandle之後,引用計數減1,當變爲0時,系統刪除內核對象。

若在線程執行完之後,沒有調用CloseHandle,在進程執行期間,將會造成內核對象的泄露,相當於句柄泄露,但不同於內存泄露,這勢必會對系統的效率帶來一定程度上的負面影響。但當進程結束退出後,系統會自動清理這些資源。

from:http://blog.csdn.net/lhsxsh/archive/2009/02/18/3905505.aspx

發佈了34 篇原創文章 · 獲贊 15 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章