2012-03-15 84 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