2012-03-15 102 views
5

我開始使用AfxBeginThread的線程。這會返回一個指向新的CWinThread對象的指針。在AfxBeginThread創建後誰擁有CWinThread?

MSDN聲明這個指針是NULL,它將在線程創建失敗時釋放所有的東西。然而,只要線程在定期啓動後退出,對象仍然存在。我不知道是否應該刪除CWinThread對象,或者如果這是由MFC自己完成的(雖然看起來不是這樣)。

僅供參考線程不可能退出,因爲它應該運行直到應用程序結束。然而,因爲我使用它作爲線程池的一部分,所以我不希望CWinThread永遠不能掛起。

回答

2

如果您的線程仍在運行,則不應將其刪除。一旦停止,只是爲了釋放被該線程使用的內存使用操作deleteAfxBeginThread返回的指針:

CWinThread *thread = AfxBeginThread(...); 
/* ... */ 
// now wait for it to terminate 
WaitForSingleObject(thread->m_hThread, INFINITE); 
delete thread; 

您應該CWinThread指針存儲到你的線程/應用程序結束,這樣就可以釋放分配給他們的內存。否則,你會有內存泄漏。

+4

這個答案是錯誤的。線程終止後,'CWinThread'將關閉線程句柄,並刪除它自己。因此,這段代碼可能會在一個關閉的句柄上調用'WaitForSingleObject',這是未定義的行爲,或者它可能試圖刪除一個已經被刪除的對象。正確的做法是在_suspended_線程上使用'm_bAutoDelete',正如@jla的回答中所解釋的。 – 2016-01-05 02:49:48

4

我從來不信任CWinThread自行清理。我通常創建線程和我告訴MFC我做了清理,程序關閉時特地:

CWinThread *thread = AfxBeginThread(...); 
thread->m_bAutoDelete = FALSE; 

你會的,但是,必須保存線程指針否則,你將有內存泄漏。

+0

謝謝,我剛剛發現了關於m_bAutoDelete成員,並按照您和@fontanini的建議進行操作。 +1 – Alex 2012-03-16 09:58:15

+3

這個答案是錯誤的。當這段代碼試圖設置'm_bAutoDelete'時,'CWinThread'對象可能已經自己刪除了。請參閱@jla回答如何正確使用此技術。 – 2016-01-05 02:51:53

+0

我不同意答案是錯的。答案的關鍵是m_bAutoDelete,爲簡潔起見,示例中的參數「...」省略。 CREATE_SUSPENDED也是必要的,如果不是,你的評論是正確的。我同意@吉拉的答案更完整。 – 2016-01-07 02:00:42

7

清理CWinThread對象的責任取決於它的m_bAutoDelete值。默認是刪除自己。對於火和忘記短線程這很好。它會自行清理。

如果您的線程長時間運行並需要被告知是時候退出或以其他方式進行交互,您需要CWinThread句柄保持有效並且不指向自我刪除的對象。

如果將m_bAutoDelete設置爲FALSE,則聲明您有責任刪除它。爲了使用返回的指針安全地播放它,您應該創建暫停並將其設置爲FALSE,然後再按Joseph Newcomer在其文章Using Worker Threads中所建議的方式進行恢復。

thread = AfxBeginThread(proc, this, 
         THREAD_PRIORITY_NORMAL, // default: use it 
         0,  // default stack size 
         CREATE_SUSPENDED); // let us set auto delete 
    if(thread) { // protect against that rare NULL return 
     thread->m_bAutoDelete = FALSE; 
     thread->ResumeThread(); 
    } 
+2

這是唯一正確的答案。另外兩個答案是錯誤的,可能會導致未定義的行爲。 – 2016-01-05 02:46:09

+0

如果您有一個m_bAutoDelete = TRUE的GUI線程,並且您觀察到線程不會退出,但用戶單擊了主窗口的「關閉」按鈕,則可能需要在PostNcDestroy()中調用PostQuitMessage()。 – Elmue 2016-02-09 02:15:59

+1

另請注意,如果您在線程後自行清理(m_bAutoDelete = FALSE),您仍然希望在刪除對象之前等待線程退出 – Luis 2016-11-29 00:33:02

相關問題