最近在写一个CAN总线的上位机软件,利用CAN转USB的设备连到电脑上,进行数据的传输。在接收下位机发送的数据的时候采用的在线程中持续接收数据。

1、在连接设备的函数中,开启线程。

//在创建线程的时候,将线程挂起,挂起的线程可设置下面的m_bAutoDelete 等属性,再进行线程的唤醒

m_pThread = AfxBeginThread(ReceiveThread,this,,CREATE_SUSPENDED,NULL);
m_pThread->m_bAutoDelete = false;

2、线程唤醒

ResumeThread(m_pThread->m_hThread);

3、线程挂起

SuspendThread(m_pThread->m_hThread);

4、线程结束

线程结束呢,网上最推荐的方法是线程函数正常返回,即某个变量达到某个标准,退出循环,结束线程。

UINT CTest_OilDlg::ReceiveThread(void *param)
{
while()
{
Sleep();
if(dlg->m_connect == )
{
break;
}
// 其他操作
}
}

上面满足m_connect == 0,即设备断开该循环就结束,线程函数就会进行正常返回。在结束线程的地方写如下代码

::WaitForSingleObject(m_pThread->m_hThread,INFINITE);
delete m_pThread;
m_pThread = NULL;//不太懂
WaitForSingleObject该函数是等待线程运行结束,即线程结束后置空线程。但是在使用该函数的时候,子线程里面不能有更新界面的操作,比如更新某个控件。因为这个函数是个阻塞函数,不仅阻塞线程也会阻塞消息。也就是说该函数要等待线程结束,而线程中如果有更新界面的操作,则需要界面的这个主线程给一个反应,但是此时界面的主线程被waitForSingleObject函数阻塞着,也就是进入了一个死锁的境遇。
这个时候可以改用MsgWaitForMultipleObjects这个函数,这个函数是微软针对waitForSingleObject会阻塞消息给出的一个函数,MsgWaitForMultipleObjects不会阻塞消息。
也就是上面的代码可以改写成如下:
    
DWORD dwRet = ;
MSG msg;
while(true)
{
//等待处理数据线程结束,和等待消息队列中的任何消息
dwRet = MsgWaitForMultipleObjects(,&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 + :
//get the message from Queue and dispatch it to specific window
PeekMessage(&msg,NULL,,,PM_REMOVE);
DispatchMessage(&msg);
continue;
default:
break;
}
break;
}
//CloseHandle(m_pThread->m_hThread);
delete m_pThread;
m_pThread = NULL;//不太懂

关于WaitForMultipleObjects(参考https://www.cnblogs.com/shangdawei/p/4015772.html

DWORD WaitForMultipleObjects(
DWORD dwCount, //等待的内核对象个数
CONST HANDLE* phObjects, //一个存放被等待的内核对象句柄的数组
BOOL bWaitAll, //是否等到所有内核对象为已通知状态后才返回
DWORD dwMilliseconds); //等待时间
HANDLE h[]; //句柄数组
//三个进程句柄
h[] = hProcess1;
h[] = hProcess2;
h[] = hProcess3;
DWORD dw = WaitForMultipleObjects(, h, FALSE, ); //等待3个进程结束
switch (dw)
{
case WAIT_FAILED:
// 函数呼叫失败
break; case WAIT_TIMEOUT:
// 超时
break; case WAIT_OBJECT_0 + :
// h[0](hProcess1)所代表的进程结束
break; case WAIT_OBJECT_0 + :
// h[1](hProcess2)所代表的进程结束
break; case WAIT_OBJECT_0 + :
// h[2](hProcess3)所代表的进程结束
break;
}

C++ 线程的创建、挂起、唤醒和结束 &&&& 利用waitForSingleObject 函数陷入死锁的问题解决的更多相关文章

  1. 线程概念( 线程的特点,进程与线程的关系, 线程和python理论知识,线程的创建)

    参考博客: https://www.cnblogs.com/xiao987334176/p/9041318.html 线程概念的引入背景 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运 ...

  2. python 全栈开发,Day41(线程概念,线程的特点,进程和线程的关系,线程和python 理论知识,线程的创建)

    昨日内容回顾 队列 队列 : 先进先出.数据进程安全 队列实现方式: 管道 + 锁 生产者消费者模型 : 解决数据供需不平衡 管道 双向通信 数据进程不安全 EOFError: 管道是由操作系统进行引 ...

  3. python全栈开发,Day41(线程概念,线程的特点,进程和线程的关系,线程和python理论知识,线程的创建)

    昨日内容回顾 队列 队列:先进先出.数据进程安全 队列实现方式:管道+锁 生产者消费者模型:解决数据供需不平衡 管道 双向通信,数据进程不安全 EOFError: 管道是由操作系统进行引用计数的 必须 ...

  4. 基础学习day11--多线程一线程的创建,运行,同步和锁

    一.线程基本概述 1.1.进程和线程 进程:一个应用程序一般都是一个进程,正在进行的程序 每一个进程最少都有一个线程,都有一个执行顺序,该顺序是一个执行路径或者一个控制单元 线程:进程中一个独立的控制 ...

  5. 漫谈并发编程(二):java线程的创建与基本控制

    java线程的创建 定义任务           在java中使用任务这个名词来表示一个线程控制流的代码段,用Runnable接口来标记一个任务,该接口的run方法为线程运行的代码段. public ...

  6. java 添加一个线程、创建响应的用户界面 。 演示示例代码

    javajava 添加一个线程.创建响应的用户界面 . 演示示例代码 来自thinking in java 4 21章  部分的代码  夹21.2.11 thinking in java 4免费下载: ...

  7. ACE线程管理机制-线程的创建与管理

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581369.html 有过在不同的操作系统下用c++进行过多线程编程的朋友对那些线程处理 ...

  8. Java多线程系列 基础篇02 线程的创建和运行

    1.线程创建的方式常用有两种 1. 继承 Thread 类创建线程 2. 实现 Runnable 接口创建线程 2.Thread 和 Runnable的区别 Thread和Runnable的相同点:都 ...

  9. C/C++ Muti-Thread多线程编程学习(之)线程Thread | 创建、运行、结束

    文章目录 前言 线程 Thread 创建线程 CreateThread _beginthread _beginthreadex pthread_create 线程运行 结束线程 前言   多线程(Mu ...

随机推荐

  1. 随堂小测app(nabcd)

    N 现在,老师想要组织测验,需要提前印制试卷,费时费力,考勤采取传统的点名的方式,过程繁琐且结果水分大. 而随堂小测app通过在线答题,智能定位可以帮助老师掌握学生对知识的掌握程度,了解学生的到客情况 ...

  2. python3 对excel读、写、修改的操作

    一.对excel的写操作实例: 将一个列表的数据写入excel, 第一行是标题,下面行数具体的数据 import xlwt #只能写不能读 stus = [['姓名', '年龄', '性别', '分数 ...

  3. appium 中手势密码的定位坐标

    原文地址http://www.cnblogs.com/smallTestKK/p/5408143.html 1.press方法中的坐标为绝对坐标,moveTO方法中的坐标都是相对坐标,具体来说第一个m ...

  4. javascript 中的 parameter vs arguments

    像往常一样简单粗暴地看码: A parameter is the variable which is part of the method’s signature (method declaratio ...

  5. java.sql.SQLException: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' 异常处理,及MySQL数据库编码设置

    java.sql.SQLException: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,C ...

  6. JavaEE学习记录(一)--软件系统体系结构

    1 常见软件系统体系结构B/S.C/S 1.1 C/S l C/S结构即客户端/服务器(Client/Server),例如QQ: l 需要编写服务器端程序,以及客户端程序,例如我们安装的就是QQ的客户 ...

  7. PHP分页及原理

    在看本文之前,请确保你已掌握了PHP的一些知识以及MYSQL的查询操作基础哦. 作为一个Web程序,经常要和不计其数的数据打交道,比如会员的数据,文章数据,假如只有几十个会员那很好办,在一页显示就可以 ...

  8. AVAudioSession(4):响应音频中断事件

    本文转自:AVAudioSession(4):响应音频中断事件 | www.samirchen.com 本文内容主要来源于 Responding to Interruptions. 当一个音频中断到来 ...

  9. 第三方CSS安全吗?

    原文:https://jakearchibald.com/201...翻译:疯狂的技术宅 本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推送新鲜的前端技术文章 前一段时间,有很 ...

  10. nginx结合fastcgi

    1.首先安装nginx,这里采用编译安装 useradd -M -s /sbin/nologin nginx 安装一些依赖包: yum -y install pcre-devel libxslt-de ...