首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

请教小弟我这段多线程代码为什么会死机

2014-04-18 
请问我这段多线程代码为什么会死机?我在写个多线程的代码,建立一个对话框,放置“开始”“通知”“进度条”控件。

请问我这段多线程代码为什么会死机?
我在写个多线程的代码,建立一个对话框,放置“开始”“通知”“进度条”控件。我的目的是按“开始”执行“ThreadFunc”函数,按“停止”中止执行。代码如下:

C/C++ code
void  CSolverDlg::ForceQuit(){    SetEvent(hExit);};BOOL CSolverDlg::IsForceQuit(){    return WaitForSingleObject(hExit,0) == WAIT_OBJECT_0 ;};void CSolverDlg::OnBnClickedStart(){    // TODO: 在此添加控件通知处理程序代码    if (m_MyThread != NULL)    {        DWORD dwExitCode = -1;        VERIFY( GetExitCodeThread(*m_MyThread, &dwExitCode) );        if (dwExitCode == STILL_ACTIVE)        {            TRACE("是否在运行1\n");            return;        }        delete m_MyThread;        m_MyThread = NULL;    }    m_MyThread =AfxBeginThread(    ThreadFunc,    (LPVOID)this,    THREAD_PRIORITY_NORMAL,    0,    CREATE_SUSPENDED,    NULL);    ASSERT(m_MyThread);    m_MyThread->m_bAutoDelete = FALSE;    m_MyThread->ResumeThread();}void CSolverDlg::OnBnClickedStop(){    // TODO: 在此添加控件通知处理程序代码    if (m_MyThread != NULL)    {        DWORD dwExitCode = -1;        VERIFY( GetExitCodeThread(*m_MyThread, &dwExitCode) );        if (dwExitCode == STILL_ACTIVE)        {            ForceQuit();            WaitForSingleObject(*m_MyThread,INFINITE);            delete m_MyThread;            m_MyThread = NULL;        }    }    else    TRACE("已结束\n");}UINT ThreadFunc(LPVOID pParam){    CSolverDlg * pMain = (CSolverDlg *) pParam; //强制转换获得传入的类对象指针    pMain->m_Progress.SetRange(0, 30 );    for (int i=0; i<30; i++)    {        TRACE("在运行11\n") ;        if (pMain->IsForceQuit())         {            TRACE("停止1\n") ;            return -1;        }        TRACE("在运行13\n") ;        Sleep(5000);//休眠5秒钟        TRACE("在运行14\n") ;        pMain->m_Progress.SetPos(i);        TRACE("在运行12\n") ;    }    return 0;};

当按停止键时,执行到“pMain->m_Progress.SetPos(i);”这步就死机了,这是为什么?

[解决办法]
“pMain->m_Progress.SetPos(i);”会通过SendMessage函数给主线程发送消息,但是此时主线程处于“WaitForSingleObject(*m_MyThread,INFINITE);”的等待中,无法处理消息,造成死锁。

特别提示:线程函数尽量不要操作UI界面。
解决方案有两个:
一个是“pMain->m_Progress.SetPos(i);”通过给主线程PostMessage方式,让主线程更新。
另一个是“WaitForSingleObject(*m_MyThread,INFINITE);”替换成while循环,使用PeekMessage和带超时的WaitForSingleObject函数调用组合检测线程是否退出。


[解决办法]
跨线程SendMessage,比如在线程A中给主线程发消息,线程A会挂起,直到主线程里这个消息处理完。MFC里很多成员函数内部都是通过SendMessage来实现的。

热点排行