VC++关于使用WaitForSingleObject等待线程安全退出,出现死机问题的解决

简介: VC++关于使用WaitForSingleObject等待线程安全退出,出现死机问题的解决

1、MFC项目场景如下:


主线程新建了子线程:


CWinThread *m_pThread_SysReset;


m_pThread_SysReset= AfxBeginThread(ThreadSysReset this);


主界面等待子线程退出时,主线程主动调用了函数:

WaitForSingleObject(m_pThread_SysReset->m_hThread, INFINITE);

目的是让子待线程安全退出,但是子线程此时正在执行SendMesage发消息函数,主线程就会卡死。而如果子线程改为PostMessage发就不会卡死。为什么呢?


原来在工作线程中使用了SendMesage,它是阻塞方式发消息,这样的话在主线程中使用了waitforSingleObject,主线程就会被阻塞,要是工作线程也使用了消息循环与主线程相关的操作,那么因为主线程已经被阻塞了,所以子线程得不到相应,那么就出现假死了。


实际上,我们可以不使用WaitForSingleObject,因为MFC主线程在不被关闭的话是不会结束的,所以不能使用WaitForSingleObject这样的函数进行等待。但是很多情况下,我们又需要知道我们创建的工作线程的情况,所以还是需要了解工作线程的返回值。那么我们可以使用微软提供的另一个函数MsgWaitForMultipleObjects。


2、怎么解决SendMessage死机问题?使用以下源码即可解决!不再使用WaitForSingleObject,而是使用MsgWaitForMultipleObjects函数。


如此一来,无论子线程怎么发消息,SendMessage也好,PostMessage也罢,都OK!


m_pThread_SysReset = ThreadFun_StartRun(&m_pThread_SysReset, ThreadSystemReset, this);
void CViewImage::ThreadFun_ExitThread(void)
{
  m_bExit = true;
  ThreadFun_WaitForObject(&m_pThread_SysReset);//等待线程退出
}
CWinThread *CViewImage::ThreadFun_StartRun(CWinThread **pThread, AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority)
{
  if (*pThread != NULL)
  {
  delete *pThread;
  *pThread = NULL;
  }
  //启动线程,初始为挂起状态
  *pThread = AfxBeginThread(pfnThreadProc, pParam, nPriority, 0, CREATE_SUSPENDED);
  if (*pThread != NULL)
  {
  //线程结束时不自动撤销
  (*pThread)->m_bAutoDelete = FALSE;
  //恢复线程运行
  (*pThread)->ResumeThread();
  }
  return *pThread;
}
void CViewImage::ThreadFun_WaitForObject(CWinThread **pThread)
{
  if (*pThread == NULL)
  {
  return;
  }
  while (1)
  {
  DWORD result;
  MSG msg;
  result = MsgWaitForMultipleObjects(1, &(*pThread)->m_hThread, FALSE, INFINITE, QS_ALLINPUT);
  if (result == WAIT_OBJECT_0 + 1)
  {
    //响应windows消息
    PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  else
  {
    //线程运行结束(result==WAIT_OBJECT_0) ||
    //传递了一个无效的句柄(result==WAIT_FAILED) ||
    //线程等待时间已到(result==WAIT_TIMEOUT) ||
    //其他情况(...)
    break;
  }
  }
  delete *pThread;
  *pThread = NULL;
}


相关文章
|
安全 程序员 C++
C++一分钟之-原子操作与线程安全
【6月更文挑战第27天】**C++的`std::atomic`提供线程安全的原子操作,解决多线程数据竞争。涵盖原子操作概念、应用、问题与对策。例如,用于计数器、标志位,但选择数据类型、内存顺序及操作组合需谨慎。正确使用能避免锁,提升并发性能。代码示例展示自旋锁和线程安全计数。了解并恰当运用原子操作至关重要。**
569 1
|
设计模式 安全 编译器
【代码片段】【C++】C++11线程安全单例模式
【代码片段】【C++】C++11线程安全单例模式
385 1
|
设计模式 安全 C++
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
674 2
|
存储 安全 Linux
【C/C++ 可重入函数与不可重入函数】理解C/C++ 中函数的可重入性以及与线程安全性的关系
【C/C++ 可重入函数与不可重入函数】理解C/C++ 中函数的可重入性以及与线程安全性的关系
1360 0
【C/C++ 可重入函数与不可重入函数】理解C/C++ 中函数的可重入性以及与线程安全性的关系
|
安全 Linux 编译器
从C语言到C++_40(多线程相关)C++线程接口+线程安全问题加锁(shared_ptr+STL+单例)(下)
从C语言到C++_40(多线程相关)C++线程接口+线程安全问题加锁(shared_ptr+STL+单例)
395 0
|
安全 C语言 C++
从C语言到C++_40(多线程相关)C++线程接口+线程安全问题加锁(shared_ptr+STL+单例)(中)
从C语言到C++_40(多线程相关)C++线程接口+线程安全问题加锁(shared_ptr+STL+单例)
732 0
|
Linux 调度 C语言
从C语言到C++_40(多线程相关)C++线程接口+线程安全问题加锁(shared_ptr+STL+单例)(上)
从C语言到C++_40(多线程相关)C++线程接口+线程安全问题加锁(shared_ptr+STL+单例)
436 0
|
存储 开发框架 安全
【C++ 线程】深入理解C++线程管理:从对象生命周期到线程安全
【C++ 线程】深入理解C++线程管理:从对象生命周期到线程安全
1639 0
|
安全
C++11 线程安全的队列模板
C++11 线程安全的队列模板
320 0
|
安全
C++11线程安全队列和安全栈
C++11线程安全队列和安全栈
427 0

热门文章

最新文章