今天做多线程,想实现断网自动重连的功能
原来的写法是
CWinThread* ptimerThread; if(ptimerThread==NULL) {ptimerThread=AfxBeginThread(threadFunTimer,NULL);}
发现这样的写法多线程只能调用一次,线程结束后ptimerThread并不跟着变成NULL,再想创建这个线程就不行了。
后来问别人才知道,可以通过WaitForSingleObject来判断线程是否结束。
加代码如下
DWORD m_ret=WaitForSingleObject(ptimerThread->m_hThread,0); if (m_ret== WAIT_OBJECT_0) {ptimerThread=AfxBeginThread(threadFunTimer,NULL);}
测试结果发现m_ret并不等于WAIT_OBJECT_0;而是等于WAIT_FAILED,0xFFFFFFFF
另一种方法是可以通过GetExitCodeThread来判断是否线程结束
于是改成代码如下,这应该是一种成功的算法
DWORD m_ret=WaitForSingleObject(ptimerThread->m_hThread,0); if (m_ret== WAIT_OBJECT_0) {ptimerThread=AfxBeginThread(threadFunTimer,NULL);} else { DWORD ExitCode; DWORD ErrCode; BOOL bval = GetExitCodeThread( ptimerThread->m_hThread, &ExitCode ); if( bval==true) { if(ExitCode==STILL_ACTIVE) { ::MessageBox(NULL, _T("线程正在连接"), _T("提示"), MB_OK); } else { //经验证线程关闭后并未进入此代码段 } else ( bval==false) { ErrCode=GetLastError();//线程结束后进入此代码段,且返回错误码为0,〖0〗-操作成功完成。 ptimerThread=AfxBeginThread(threadFunTimer,NULL); } }
原本以为错误码是0也是错误,接着改成下面的代码
if(ptimerThread==NULL) { ptimerThread=AfxBeginThread(threadFunTimer,NULL,THREAD_PRIORITY_NORMAL,0, CREATE_SUSPENDED);//用挂起方式执行 ASSERT(ptimerThread); ptimerThread->m_bAutoDelete = FALSE;设置m_bAutoDelete,这个参数可以阻止CWinThread对象被自动删除。 ptimerThread->ResumeThread(); }
如此创建线程后
if (m_ret== WAIT_OBJECT_0) {ptimerThread=AfxBeginThread(threadFunTimer,NULL);}
这段好用了,这也是一种成功的方法。
再试试GetExitCodeThread
DWORD ExitCode; DWORD ErrCode; BOOL bval = GetExitCodeThread( ptimerThread->m_hThread, &ExitCode ); if( bval==true) { if(ExitCode==STILL_ACTIVE) { ::MessageBox(NULL, _T("线程正在连接"), _T("提示"), MB_OK); } else { //此时线程关闭后进入此代码段,ExitCode为线程退出时写的值,如 return 2,则ExitCode=2; ptimerThread=AfxBeginThread(threadFunTimer,NULL,THREAD_PRIORITY_NORMAL,0, CREATE_SUSPENDED);//用挂起方式执行 ASSERT(ptimerThread); ptimerThread->m_bAutoDelete = FALSE;设置m _bAutoDelete,这个参数可以阻止CWinThread对象被自动删除。 ptimerThread->ResumeThread(); }
这个也成功了。前面失败的原因就是设置m_bAutoDelete,这个参数可以阻止CWinThread对象被自动删除。如果未设置,则线程结束时CWinThread对象
自动删除,DWORD m_ret=WaitForSingleObject(ptimerThread->m_hThread,0);返回值则为失败,BOOL bval = GetExitCodeThread( ptimerThread->m_hThread, &ExitCode ); bval 也为false,错误码ExitCode=0,0代表操作成功完成。