void CP_CDlg::Init()
{
this->m_pProducerThread =new CProducerThread(this);
this->m_pProducerThread->CreateThread(CREATE_SUSPENDED);
VERIFY(m_pProducerThread->SetThreadPriority(THREAD_PRIORITY_IDLE));
this->m_pProducerThread->ResumeThread();
}

int CProducerThread::Run() 
{
CP_CDlg *pDlg;
pDlg=(CP_CDlg*)m_pParentDlg;
CSingleLock mutexLock(pDlg->m_pMutex);
for(int i=0;i<MAX_DATA_COUNT;i++)
{
pDlg->m_pSemaphoreEmpty->Lock();
mutexLock.Lock();
pDlg->m_sBuf.Format("%0.10d",i);
mutexLock.Unlock();
pDlg->m_pSemaphoreFull->Unlock();
} return CWinThread::Run();
}
既然有new 就应该 有delete,如何添加?

解决方案 »

  1.   

    构造一个Event,在CProducerThread::Run() return之前SetEvent
    在需要释放内存的时候(比如程序结束),WaitForSingleObject(hEvent),Wait成功之后删除CWinThread对象。
      

  2.   

    重载对话框CP_CDlg的OnDestroy()函数,在里面delete对象
    void CP_CDlg::OnDestroy()
    {
        delete this->m_pProducerThread;
        //
        CDialog::OnDestroy();
    }
      

  3.   

    int CProducerThread::Run() 
    {
    CP_CDlg *pDlg;
    pDlg=(CP_CDlg*)m_pParentDlg;
    CSingleLock mutexLock(pDlg->m_pMutex);
    for(int i=0;i<MAX_DATA_COUNT;i++)
    {
    pDlg->m_pSemaphoreEmpty->Lock();
    mutexLock.Lock();
    pDlg->m_sBuf.Format("%0.10d",i);
    mutexLock.Unlock();
    pDlg->m_pSemaphoreFull->Unlock();
    } int r=CWinThread::Run();
             delete this;
             return r;}
      

  4.   

    to LongLongAgoImBoy(ThereIsAMe) :
    你的代码会造成this->m_pProducerThread线程的非正常退出,可能导致不确定的问题。成熟的代码是不会这么写的。to  Kevin_qing():
    你的代码也许是可行的,但是违背了一个编码原则:谁分配谁负责。主线程很可能在不知情的情况下访问this->m_pProducerThread 而导致出错。
      

  5.   

    从CProducerThread里发个消息回来关闭就是了:
    int CProducerThread::Run() 
    {
    CP_CDlg *pDlg;
    pDlg=(CP_CDlg*)m_pParentDlg;
    CSingleLock mutexLock(pDlg->m_pMutex);
    for(int i=0;i<MAX_DATA_COUNT;i++)
    {
    pDlg->m_pSemaphoreEmpty->Lock();
    mutexLock.Lock();
    pDlg->m_sBuf.Format("%0.10d",i);
    mutexLock.Unlock();
    pDlg->m_pSemaphoreFull->Unlock();
    } int r=CWinThread::Run();
             // send message to CP_CDlg to release the allocated memory
             SendMessage(...);         return r;}
      

  6.   

    能用SDK的尽量就不要用MFC,封装那么多东西,搞得笨重得不得了!
      

  7.   

    给CProducerThread类添加一个ExitInstance()函数(这是它自己带的消息响应函数)int CProducerThread::ExitInstance()
    {
       if(m_pProducerThread != NULL)
       { 
          delete pProducerThread  ;
          pProducerThread  = NULL ;
        }
       return CProducerThread::ExitInstance();
    }然后在
    int CProducerThread::Run() 
    {
       ........
       ........
       return ExitInstance();
       //return CProducerThread::Run();  这句原来的返回注释掉!
    }
      

  8.   

    to a_kun:
    SendMessage出去,然后让外面来释放自己显然是不健康的。SendMessage的时候,ProducerThread线程还没退出,但是却要求其他线程释放自己,我想这必然导致其他线程释放一个还没结束的ProducerThread。用PostMessage也许会好一些,但是由于线程调度的不确定性,PostMessage也不是完全健康的。to jiuzhoulh:
    你的解决方法和Kevin_qing的方法比较接近。也许都是可用的,但我想都不是最健康的。
      

  9.   

    a_kun(狂人日记) 的就差不多了,sendmessage最好变成postmessage,只要保证在通知后不再做些jjyy的事(通知之后可以看做线程已经结束),看上去合情合理,wwwsq(wwwsq) 要搞懂线程的概念,不要把线程当成一个对象,这样不会被搞晕.new CProducerThread(this),只不过是new了一堆关与线程的数据而以,线程本身运行不依赖与这堆数据,这堆数据只有在其它线程对该线程通信时才有用.建议看sdk,自己写个线程类,自己学习一下.
      

  10.   

    CWinThread::m_bAutoDelete = TRUE;
      

  11.   

    可以解决问题就行了,mfc怎么看都比较怪异,非常之不喜欢
      

  12.   

    实际上我见过很多商业代码,大部分都或多或少有些不健康的部分。因此在代码的健康度和开发成本之间要做一个平衡。
    对于关键代码,无论如何要保证代码的健康。非关键代码,可以适度考虑简洁的实现方法。PS:我做了整整四年的工业级应用软件,对于不健康代码带来的问题有切肤之痛。关于MFC,我觉得MFC本身其实很好的,只是要看在什么场合如何应用它。比如很多人说CString不好用,我想那只是在错误的场合错误的使用了CString。
      

  13.   

    CProducerThread这个是从MFC线程类派生的吧?
    那么线程结束时会自己delete this
      

  14.   

    从mfc的代码来看,UI线程在delete自己之前有很多的工作要做。
    比如threadWnd.Detach();
    比如(*pThread->m_lpfnOleTermOrFreeLib)(TRUE, FALSE);delete之后也还有很多工作要做:
    比如pThreadState->m_pToolTip->DestroyWindow();
    比如delete pThreadState->m_pToolTip;
    比如_afxThreadData->DeleteValues(hInstTerm, FALSE);
    比如_endthreadex(nExitCode);这么多事情没做,居然还敢声称直接delete this是安全的?
      

  15.   

    看来CWinThread的结束和释放远非这么简单。从代码来看,m_bAutoDelete只是影响AfxEndThread(nResult)的时候delete this调用与否。CWinThread线程的退出彻底与否,取决于CWinThread能否完整正确的执行threadWnd.Detach()和AfxEndThread(nResult)。过早的在CWinThread线程运行过程中调用delete this有可能导致threadWnd.Detach()和AfxEndThread(nResult)不能完整正确的执行。实际上我写服务器程序的时候,从不用UI线程。需要消息队列的时候,都是自己在worker thread里面GetMessage()我对使用mfc的态度是,要么不用,要么就用微软给出的最标准的方法调用。写程序的时候不可能每个地方都进行细节分析的,尤其是面对mfc这样的庞然大物的时候。
      

  16.   

    同意楼上观点
    我做开发3年来,一直不强调区分UI线程和工作线程,无意义,只会搞混思维,但有一个原则:所有的UI操作只放在一个线程处理.PS:楼主给的代码并非UI线程
      

  17.   

    To wwwsq:
      蒙你的高见,实际上偶可以这样做,既然上面的线程由外面的进程来控制,那么当外面的进程想结束程序,那么可以先向线程发出一个信号(用全局bool型变量表示),当线程检测到该信号为真时,即处理其内部资源占用问题,处理完毕后退出线程,然后由外部的进程来处理上面的new,这样一来可以说安全的多。