16,472
社区成员
发帖
与我相关
我的任务
分享
/*
提取 CWinThread 对象的退出码需要额外的步骤. 默认时, CWinThread 线程终止时,
线程对象被删除了.就是说不能再存取 m_hThread 数据成员,因为 CWinThread 对象不再存在.
为此,要用如下2个方法之一:
设置 m_bAutoDelete 数据成员为 FALSE.
这样线程终止后 CWinThread 对象还在. 就可以存取 m_hThread 了. 使用这种方法要自己销毁
CWinThread 对象, framework 不会自动删除它了. 这是提倡的方法.
或者:
创建线程后立刻把线程句柄保存起来. 即复制 m_hThread (使用::DuplicateHandle)到另一个变量
并通过这个变量来存取. 这样对象终止时自动被删除,但你可以得到线程退出的原因.
注意在复制局柄前,线程不能退出. 安全的方法是创建线程时先 CREATE_SUSPENDED, 然后再ResumeThread.
*/
void CloseThread()
{
if((m_threaddraw==0) && (m_threadcomm==0)) return;
//
#if 1 // if must auto delete, such as there are resources have to be released
g_bExit=TRUE;
while(m_threadcomm->ResumeThread() != 0);
//
DWORD ret=WaitForSingleObject(m_threadcomm->m_hThread, 1000);//INFINITE);
if(WAIT_TIMEOUT==ret) AfxMessageBox("WAIT_TIMEOUT comm");
ret=WaitForSingleObject(m_threaddraw->m_hThread, 1000);//INFINITE);
if(WAIT_TIMEOUT==ret) AfxMessageBox("WAIT_TIMEOUT draw");
// "m_hThread signaled" does not mean thread is exits.
#ifdef CHECK_EXIT_CODE
DWORD ex;
do
{
if(!GetExitCodeThread(m_htmpcomm, &ex))
{// kill the thread
if(m_threadcomm) m_threadcomm->Delete();
break;
}
} while(ex==STILL_ACTIVE);
DWORD ex1;
do
{
if(!GetExitCodeThread(m_htmpdraw, &ex1))
{// kill the thread
if(m_threaddraw) m_threaddraw->Delete();
break;
}
} while(ex1==STILL_ACTIVE);
// BOOL rt=CloseHandle(m_htmpcomm);
// rt=CloseHandle(m_htmpdraw);
AfxMessageBox("Threads Exited with 0");
#endif
//
#else // if can terminate, that is , kill the threads.
if(m_threadcomm) m_threadcomm->Delete();
if(m_threaddraw) m_threaddraw->Delete();
#endif
}
// run or stop
void CCEventDlg::OnButton1()
{
static BOOL stop=FALSE;
if(!stop)
{
GetDlgItem(IDC_BUTTON1)->SetWindowText("暂停");
if((m_threaddraw==0) && (m_threadcomm==0))
{
m_threaddraw=AfxBeginThread(AFX_THREADPROC(draw),(LPVOID)this,
THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL);
// afxDump << this << "\n";
m_threadcomm=AfxBeginThread(AFX_THREADPROC(ReadComm),(LPVOID)this,
THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL);
#ifdef CHECK_EXIT_CODE
DuplicateHandle(GetCurrentProcess(),m_threaddraw->m_hThread,GetCurrentProcess(),
&m_htmpcomm,0,FALSE,DUPLICATE_SAME_ACCESS);
DuplicateHandle(GetCurrentProcess(),m_threadcomm->m_hThread,GetCurrentProcess(),
&m_htmpdraw,0,FALSE,DUPLICATE_SAME_ACCESS);
#endif
m_threaddraw->ResumeThread();
Sleep(0);// 让 draw 先运行
m_threadcomm->ResumeThread();
}
else
{
while(m_threadcomm->ResumeThread()!=0);
}
}
else
{
GetDlgItem(IDC_BUTTON1)->SetWindowText("运行");
while(m_threadcomm->SuspendThread()==0);
}
stop = !stop;
}