C++ 线程的创建、挂起、唤醒和结束 &&&& 利用waitForSingleObject 函数陷入死锁的问题解决
2018-04-20 17:21
573 查看
最近在写一个CAN总线的上位机软件,利用CAN转USB的设备连到电脑上,进行数据的传输。在接收下位机发送的数据的时候采用的在线程中持续接收数据。1、在连接设备的函数中,开启线程。
//在创建线程的时候,将线程挂起,挂起的线程可设置下面的m_bAutoDelete 等属性,再进行线程的唤醒 m_pThread = AfxBeginThread(ReceiveThread,this,0,CREATE_SUSPENDED,NULL); m_pThread->m_bAutoDelete = false;
[p]2、线程唤醒[code]ResumeThread(m_pThread->m_hThread);3、线程挂起
SuspendThread(m_pThread->m_hThread);4、线程结束线程结束呢,网上最推荐的方法是线程函数正常返回,即某个变量达到某个标准,退出循环,结束线程。[/p]
UINT CTest_OilDlg::ReceiveThread(void *param) { while(1) { Sleep(1); if(dlg->m_connect == 0) { break; } // 其他操作 } }
上面满足m_connect == 0,即设备断开该循环就结束,线程函数就会进行正常返回。在结束线程的地方写如下代码
::WaitForSingleObject(m_pThread->m_hThread,INFINITE); delete m_pThread; m_pThread = NULL;//不太懂
WaitForSingleObject该函数是等待线程运行结束,即线程结束后置空线程。但是在使用该函数的时候,子线程里面不能有更新界面的操作,比如更新某个控件。因为这个函数是个阻塞函数,不仅阻塞线程也会阻塞消息。也就是说该函数要等待线程结束,而线程中如果有更新界面的操作,则需要界面的这个主线程给一个反应,但是此时界面的主线程被waitForSingleObject函数阻塞着,也就是进入了一个死锁的境遇。
这个时候可以改用MsgWaitForMultipleObjects这个函数,这个函数是微软针对waitForSingleObject会阻塞消息给出的一个函数,MsgWaitForMultipleObjects不会阻塞消息。
也就是上面的代码可以改写成如下:
DWORD dwRet = 0; MSG msg; while(true) { //等待处理数据线程结束,和等待消息队列中的任何消息 dwRet = MsgWaitForMultipleObjects(1,&m_pThread->m_hThread,false,INFINITE,QS_ALLINPUT); //dwRet = WaitForSingleObject(m_pThread->m_hThread,50); switch (dwRet) { case WAIT_OBJECT_0: break; case WAIT_OBJECT_0 + 1: //get the message from Queue and dispatch it to specific window PeekMessage(&msg,NULL,0,0,PM_REMOVE); DispatchMessage(&msg); continue; default: break; } break; } //CloseHandle(m_pThread->m_hThread); delete m_pThread; m_pThread = NULL;//不太懂
关于WaitForMultipleObjects(参考https://www.geek-share.com/detail/2623922000.html)
DWORD WaitForMultipleObjects( DWORD dwCount, //等待的内核对象个数 CONST HANDLE* phObjects, //一个存放被等待的内核对象句柄的数组 BOOL bWaitAll, //是否等到所有内核对象为已通知状态后才返回 DWORD dwMilliseconds); //等待时间
HANDLE h[3]; //句柄数组 //三个进程句柄 h[0] = hProcess1; h[1] = hProcess2; h[2] = hProcess3; DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000); //等待3个进程结束 switch (dw) { case WAIT_FAILED: // 函数呼叫失败 break; case WAIT_TIMEOUT: // 超时 break; case WAIT_OBJECT_0 + 0: // h[0](hProcess1)所代表的进程结束 break; case WAIT_OBJECT_0 + 1: // h[1](hProcess2)所代表的进程结束 break; case WAIT_OBJECT_0 + 2: // h[2](hProcess3)所代表的进程结束 break; }
阅读更多
相关文章推荐
- 主线程中调用WaitForSingleObject函数造成的死锁问题
- 15.[个人]C++线程入门到进阶(15)----线程函数:WaitForSingleObject
- C++ win开发 WaitForSingleObject函数
- 对话框中WaitForSingleObject等待线程退出导致程序阻塞的原因及解决
- 【VS开发】WaitForSingleObject 和 WaitForMultipleObjects函数 (让线程挂起等待事件)
- 对话框中WaitForSingleObject等待线程退出导致程序阻塞的原因及解决
- c++中WaitForSingleObject函数解析(1)
- 在界面线程不能使用Sleep和WaitForSingleObject之类的函数
- c++中WaitForSingleObject函数解析
- WaitForSingleObject()函数,其第一个参数是一个核心对象(如线程)的 handle
- c++中WaitForSingleObject函数解析
- 线程挂起和逐个执行之CreateEvent和WaitForSingleObject
- 在界面线程不能使用Sleep和WaitForSingleObject之类的函数, 使用 MsgWaitForMultipleObjects
- 【转】c++中WaitForSingleObject函数解析
- WaitForSingleObject或MsgWaitForMultipleObjects函数无返回,程序直接退出问题
- 在界面线程不能使用Sleep和WaitForSingleObject之类的函数, 使用 MsgWaitForMultipleObjects
- 等待线程结束的高手--WaitForSingleObject
- WaitForSingleObject或MsgWaitForMultipleObjects函数无返回,程序直接退出问题
- 对话框中WaitForSingleObject等待线程退出导致程序阻塞的原因及解决
- WaitForSingleObject 结束线程