線程何時釋放內核資源

轉載自http://hi.baidu.com/wangguang246/blog/item/eb70032817b5f3e599250aaf.html
最終編輯 yaofly

一例子1
    if(sClient!=INVALID_SOCKET)
   {
    hThread = CreateThread(NULL,0,ClientThread,(LPVOID)pClientInfo,0,&dwThread);
    //free(pClientInfo);
    if(hThread==NULL)
    {
     AfxMessageBox("Thread Creat Failed!\n");
     break;
    }
        CloseHandle(hThread);
   }


        CloseHandle關閉句柄並沒有終止新創建的線程。只是表示對新創建的線程的引用不敢興趣,系統會遞減新 線程的線程內核對象的使用計數。當使用計數爲0的時候,系統就會釋放線程內核對象。如果在主線程中沒有關閉線程的句柄,始終都會保留一個引用。這樣線程內核對象的引用計數就不會 爲0。即使新線程執行完畢,線程內核對象也不會被釋放,只有等到進程終止的時候系統纔會爲 殘留的對象做清理工作。所以應該在不再使用線程的句柄的時候將其關閉掉,讓線程的線程內核對象的引用計數減1
Closing a thread handle does not terminate the associated thread. To remove a thread object, you must terminate the thread, and then close all handles to the thread.
MSDN上的一句話!

主線程沒有任何特殊性,主線程退出並不會導致它所創建的線程退出!

在Windows上,所有的線程都是平等的,其實沒有什麼主線程和和從屬線程的區別。你可能會說:你說的不對,我的主線程結束了,我的程序就退出了。這是因爲我們大部分的程序都是Link了微軟的CRT,主函數由它導入,當main函數結束的時候,CRT會叫到:

ExitProcess

於是所有的線程都同歸於盡了。你感覺上好像其他線程都是主線程給弄沒的。如果你不用CRT,或者是直接用匯編,主線程退出的時候不影響其他的線程。

一例子2
............
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 


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