大家好,我使用多线程编程时有些问题一直没有搞明白,如下
1.使用我下面这段代码创建用户界面线程是否正确。
2.创建的线程结束后,如何通知主线程?
3.我的这个线程pMyThread需要重复使用,是否每次重新使用都是使用AfxBeginThread来创建,像我下面这样的做法?
4.因为创建的线程只有一个,并且主线程和创建的线程不会同时去操纵同一数据,所以是否可以不需关注线程同步的问题?

请高手给予解答,非常感谢!
CMyThread   * pMyThread; 
threadInfo Info ;//向线程传递的结构体参数
void CMyDlg::OnBtnStart() //启用及关闭线程的按钮
{ bool bCreateThread=FALSE;
if (pMyThread ==NULL)
{ bCreateThread=TRUE;
}else
{ GetExitCodeThread(pMyThread->m_hThread, &pMyThread->m_nThreadID);
if   (  pMyThread->m_nThreadID==0x103)   //检查线程是否在运行,如果是就停止运行
{ Info.RunState=IsStop; 
return ;
}else bCreateThread=TRUE;
} if (bCreateThread)
{ //创建线程,是否每次重新创建都是使用AfxBeginThread来创建?这样做是否有资源没有释放?
if(!(pMyThread   =   (CMyThread*)AfxBeginThread(RUNTIME_CLASS(CMyThread),   
THREAD_PRIORITY_NORMAL,  0,   CREATE_SUSPENDED))) 
{  AfxMessageBox(_T( "创建线程失败 ")); 
return   ; 

Info.RunState=IsRun; 
Info.obj=this->obj; //一个类对象
Info.myDlgHandle =this; //在线程中需要控制主线程对话框中的控件,所以在这里传递进去窗体的句柄
pMyThread->m_pThreadParams =&Info;//Info是我定义的一个结构体对象,在这里使用这种方式传递
pMyThread-> ResumeThread();  //真正开始执行线程

}CMyThread::CMyThread()
{ m_bAutoDelete   =   TRUE; }int CMyThread::Run() 
{
ASSERT_VALID(this); 
threadInfo *Info =(threadInfo*)this->m_pThreadParams;
CMyDlg * myDlg =(CMyDlg *) Info->myDlgHandle );
  CProgressCtrl * m_Progress=&myDlg ->m_Progress;
CMSHFlexGrid * m_Grid=    &myDlg->m_Grid; for ( int  i=0;i< m_Grid->GetRows()-1;i++)
{
if ( Info->RunState==IsStop)break;//在主线程中控制是否中止线程
 m_Grid->SetRow(i);
/*Info->obj.DoWorkFunction为一个需要很长的工作时间的函数,在调用时可能会有错误产生,需要弹出一个对话框,
根据用户对对话框的选择而做出是否退出线程,因为有对话框,所以需要创建用户界面线程*/
   if (!Info->obj.DoWorkFunction())
{  break;
}
//操纵主线程对话框的进度条
 m_Progress->SetPos(((double(i))/(double)m_Grid->GetRows()*100);

ExitInstance(); 
return 0; 
  //另外当线程结束后,我如何通知主线程? 现在我的做法是使用一个计时器在那检查线程的状态,这样做是否正确?
}

解决方案 »

  1.   

    是否每次重新创建都是使用AfxBeginThread来创建?这样做是否有资源没有释放?
    -----------------------------------------------------------------------------
    CMyThread对象delete掉,CloseHandle线程句柄。
    在线程中需要控制主线程对话框中的控件,所以在这里传递进去窗体的句柄
    -----------------------------------------------------------------------------
    不要在线程中操作主线程的界面,最好是通过发消息到主窗口,主窗口在消息响应里面操作。另外当线程结束后,我如何通知主线程? 现在我的做法是使用一个计时器在那检查线程的状态,这样做是否正确?
    -----------------------------------------------------------------------------
    可以检查线程句柄是否有信号来判断线程是否退出,也就是WaitForSingleObject(线程句柄),有信号就表示线程退出了。
      

  2.   

    http://download.csdn.net/source/1123495
    自己看这个例子,问题也就解决了!
      

  3.   

    谢谢你们的回复,可是,我怎么看不懂啊,
    TO:fandh,我要创建的是一个用户界面线程,而你的例子中使用CreateThread创建的线程无法显示对话框,会出错。
    TO:visualwind
    1.是否是在 int CMyThread::Run() 的ExitInstance(); 后面增加 this->Delete();?2.不要在线程中操作主线程的界面,最好是通过发消息到主窗口,主窗口在消息响应里面操作。
     但是m_Progress->SetPos(nPos)也不行吗?我看到fandh的例子也是这样做的啊
    3.“可以检查线程句柄是否有信号来判断线程是否退出”如何做?
      难道是在计时器中使用DWORD dw=WaitForSingleObjectpMyThread->m_hThread,0);
      

  4.   


    1 可以把CMyThread::m_bAutoDelete设为TRUE
    2 最好发消息到主线程,否则可能会造成多线程的冲突。
    3 你可以发消息来标示,在ExitInstance后面PostMessage,发自定义线程退出消息到主线程。
      

  5.   

    谢谢visualwind的耐心回复,这对我的帮助非常大
    在我前面的代码中有将CMyThread::m_bAutoDelete设为TRUE,是否这将表示线程结束会自动释放内存?
    另外我向线程传递参数时使用 pMyThread->m_pThreadParams =&Info; 是否可行?
    使用PostMessage放送消息的方法非常好,我正在改用这种方法!
      

  6.   


    CMyThread::m_bAutoDelete设为TRUE表示线程在退出的时候自动delete之前创建的CMyThread对象。这样是可以的:
    pMyThread->m_pThreadParams =&Info;
    pMyThread-> ResumeThread();