• 判断多线程是否退出,再创建这个线程。


    今天做多线程,想实现断网自动重连的功能
    原来的写法是

    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代表操作成功完成。

  • 相关阅读:
    2019 学霸君java面试笔试题 (含面试题解析)
    2019 大众书网Java面试笔试题 (含面试题解析)
    2019 中细软java面试笔试题 (含面试题解析)
    2019 企叮咚java面试笔试题 (含面试题解析)
    js 去掉数组对象中的重复对象
    canvas霓虹雨
    nvm的安装
    socket.io 中文文档
    Nginx(三)------nginx 反向代理
    github入门到上传本地项目
  • 原文地址:https://www.cnblogs.com/wangyuanf/p/3246349.html
Copyright © 2020-2023  润新知