xajh:
  你好。下面是我的程序段, 请参考://///////////////////////////////////////////////////////
// 将下载完的网页存入 SQL Server
/////////////////////////////////////////////////////////
UINT CMainFrame::SQLThreadFunc(LPVOID lparam)
{
CMainFrame* pFrame = (CMainFrame*) lparam;
CWebPage* pWebPage;

UINT nCount = 0;
BOOL bSaved = FALSE;

while (TRUE)
{ WaitForSingleObject(pFrame->m_hToSaveEvent, INFINITE); if (pFrame->m_bEndThread) //退出线程
break; while (TRUE)
{
pWebPage = NULL;

pFrame->m_csWebPageList.Lock(); if (!pFrame->m_listWebPageToSave.IsEmpty())
{
pWebPage = pFrame->m_listWebPageToSave.RemoveHead();
pFrame->m_nToSavePages--;
} pFrame->m_csWebPageList.Unlock(); if (pWebPage!=NULL)
{
pWebPage->SaveToSQL(); pWebPage->Empty();
delete pWebPage; pFrame->m_csWebPageList.Lock();
if (pFrame->m_listWebPageToSave.GetCount()<128 && pFrame->m_bWaitFull)
pFrame->m_bWaitFull = FALSE;  // 全部存完
pFrame->m_csWebPageList.Unlock();// pFrame->SendMessage(WM_USER_SAVESQL_STATUS, (WPARAM)0, (LPARAM)0);
pFrame->PostMessage(WM_USER_SAVESQL_STATUS, (WPARAM)0, (LPARAM)0);
}
else break; // 等待下一个事件
}
pFrame->m_csWebPageList.Lock();
pFrame->m_bWaitFull = FALSE;  // 全部存完
pFrame->m_csWebPageList.Unlock();
// pFrame->SendMessage(WM_USER_SAVESQL_STATUS, (WPARAM)0, (LPARAM)0);
pFrame->PostMessage(WM_USER_SAVESQL_STATUS, (WPARAM)0, (LPARAM)0);
} SetEvent(pFrame->m_hTerminateSQLEvent);
pFrame->SendMessage(WM_USER_THREAD_EXIT, (WPARAM) 99999, (LPARAM) 0);
// pFrame->PostMessage(WM_USER_THREAD_EXIT, (WPARAM) 99999, (LPARAM) 0);
return 0;
}

解决方案 »

  1.   

    look up the following code!
    static BOOL GameOver=FALSE;OnPaint()
    {
             .... if(GameMainThread)
    {
    GameOver=TRUE;
    GameMainThread->ResumeThread();
    ::WaitForSingleObject(GameMainThread->m_hThread,INFINITE);
    delete GameMainThread;
    GameMainThread=NULL;
    }
    GameOver=FALSE;
    GameMainThread=AfxBeginThread(GameMain,&m_hWnd,THREAD_PRIORITY_BELOW_NORMAL,0,CREATE_SUSPENDED);
    GameMainThread->m_bAutoDelete=FALSE;
    GameMainThread->ResumeThread();
          .......
    }
    UINT GameMain(LPVOID m_hWnd)
    {
    CChildView *pView=(CChildView *)CWnd::FromHandle(*(HWND *)m_hWnd);
    static int newtime=0,oldtime=0;
    while(!GameOver)
    {
    HeroStatus=1;
    newtime=::GetTickCount();
    //键盘方向控制
    if(::GetAsyncKeyState(VK_CONTROL))//Ctrl 键加速
    {
    if(::GetAsyncKeyState(VK_LEFT))
    HeroStatus=0,Hero.x-=6;
    if(::GetAsyncKeyState(VK_RIGHT))
    HeroStatus=2,Hero.x+=6;
    if(::GetAsyncKeyState(VK_UP))
    HeroStatus=1,Hero.y-=6;
    if(::GetAsyncKeyState(VK_DOWN))
    HeroStatus=1,Hero.y+=6;
    }
    else
    {
    if(::GetAsyncKeyState(VK_LEFT))
    HeroStatus=0,Hero.x-=4;
    if(::GetAsyncKeyState(VK_RIGHT))
    HeroStatus=2,Hero.x+=4;
    if(::GetAsyncKeyState(VK_UP))
    HeroStatus=1,Hero.y-=4;
    if(::GetAsyncKeyState(VK_DOWN))
    HeroStatus=1,Hero.y+=4;
    }
    if(newtime-oldtime>100)   //发射子弹延时控制
    {
    if(::GetAsyncKeyState(VK_SPACE))
    {
    if(++iBuletH==BULETNUMH)
    iBuletH=0;
    BuletH[iBuletH]=Hero;
    }
    oldtime=newtime;
    }
    CollisionCheck();
    DrawMap();
    DrawEnemy();
    DrawHero();
    DrawHeroBulet();
    DrawEnemyBulet();
    DrawHeroFrame();
    DrawEnemyFrame();
    Flip();
    // EnemyMove(NULL);
    }
    return 0;
    }
      

  2.   

    知道其句柄hThread
    TerminateThread(hThread,0);即可。
      

  3.   

    先TerminateThread(),再CloseHandle(),这样会比较安全。
      

  4.   

    每个线程都有一个线程函数,函数运行结束则线程就自动结束,所以这个线程函数通常核心是一个循环。你可以设一个变量如:int iAlive=true;ThreadPorc()
    {
       while(iAlive)
       {
          //thread codes here
       } 
       //线程扫尾代码}当你想结束它时,把iAlive设为0就可以了
      

  5.   

    每个线程都有一个线程函数,函数运行结束则线程就自动结束,所以这个线程函数通常核心是一个循环。你可以设一个变量如:int iAlive=true;ThreadPorc()
    {
       while(iAlive)
       {
          //thread codes here
       } 
       //线程扫尾代码}当你想结束它时,把iAlive设为0就可以了
      

  6.   

    使用TerminateThread是不明智的,强制终止的线程,空间得不到释放,会造成严重的内存泄漏。只能是通过某种途径去通知它,让它自我了断,才能保证安全。
    如果是最简单的工作线程(直接AfxBeginThread产生的),可以使用全局变量来通知它,这要求线程的结构是一个循环,不断查询变量的状态。
    如果从CWinThread派生了自己的线程类,就可以发窗口消息给它:
    PostThreadMessa(WM_CLOSE)
    CWindThread会响应这个退出消息,结束自己,包括关闭属于它自己的窗口。
      

  7.   

    [美] Jeffrey Richter
    Windows NT 高级编程技术.
    中提到:
    当线程是由于自然原因或自杀而死亡时,该线程中的堆栈将被撤销.
    但是该线程如果是他杀(调用TeriminateThread),windows在拥有该
    线程的进程退出之前不会撤销该堆栈.
    另外,在线程终止时,windows将通知所有挂接在这个拥有终止线程的
    进程上的Dlls,告诉它们线程将被终止.但是他杀的不会.例如,在线程
    脱离与某个Dll的挂接时,该Dll可能要往磁盘上刷新数据,如果dll
    没有得到通知,.....
    同样TerminateProcess也是一样的.
    由此,不到万不得已,不要使用TerminteThread
               在主线程中中止工作者线程,可以采用信号中止。
      

  8.   

    g_pWorker为工作线程的CWINTHREAD指针.::PostThreadMessage(g_pWorker->m_nThreadID,WMAT_EXIT,0,0);
    if(WAIT_FAILED == ::WaitForSingleObject(g_pWorker->m_hThread, INFINITE))
    {
    delete g_pWorker;
    TRACE("ERROR OCCURS WHEN THREAD EXITS");
    }
    g_pWorker= NULL;在工作线程函数中建立消息循环:
    while(::GetMessage(&msg, NULL, 0, 0))
    {
      if(msg.message == WMAT_EXIT)
      {
        ......    // 释放资源     
        RETURN;
      }
    }