主线程向子线程发送消息

参考链接:https://www.cnblogs.com/ranjiewen/p/5729539.html

1. 创建线程语句

    HANDLE hThread;
DWORD dwThreadId[3];
for (int i = 0; i < 3; i++) {
hThread = CreateThread(NULL, 0, FunProc, &i, 0, &dwThreadId[i]);
CloseHandle(hThread);
}

2. 向子线程发送消息语句。

  a. 在.cpp最上面定义#define MY_MSG WM_USER+100

        for (int j = 0; j < 3; j++) {
if (!PostThreadMessage(dwThreadId[j], MY_MSG, 0, 0)) {
printf("post message failed,errno:%d\n", ::GetLastError());
}
}

3.1 线程函数接收消息不阻塞

DWORD WINAPI FunProc(LPVOID lpParameter)
{
MSG msg;
int i = 0;
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (msg.message == MY_MSG)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
i++;
printf("i = %d\n", i);
Sleep(1000);
}
return 0;
}

此时接收消息用的是PeekMessage函数,此函数不会阻塞线程。如果此时有消息传来,那么返回的是TRUE,如果没有消息传来,返回的就是FALSE。这个函数的含义是每隔一秒输出一次i,直到有消息传递给线程,那么线程结束。

3.2 线程接收消息阻塞

DWORD WINAPI FunProc(LPVOID lpParameter)
{
MSG msg;
int i = 0;
BOOL stop_thread = FALSE;
while (!stop_thread)
{
if (GetMessage(&msg, 0, 0, 0)) {
switch (msg.message)
{
case MY_MSG:
stop_thread = TRUE;
break;
}
}
i++;
printf("i = %d\n", i);
Sleep(1000);
}
return 0;
}

此时接收消息用的是GetMessage函数,此函数会阻塞在if语句那儿,直到有消息传来,才会继续下去,所以这个线程只会输出一次i就结束了。

SubWin1.cpp

// SubWin1.cpp : implementation file
// #include "stdafx.h"
#include "Project2.h"
#include "SubWin1.h"
#include "afxdialogex.h"
#include "resource.h" // SubWin1 dialog
#define MY_MSG WM_USER+100
//const int MAX_INFO_SIZE = 20; IMPLEMENT_DYNAMIC(SubWin1, CDialog) SubWin1::SubWin1(CWnd* pParent /*=nullptr*/)
: CDialog(IDD_SubWin1, pParent)
{ } SubWin1::~SubWin1()
{
} void SubWin1::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
} BEGIN_MESSAGE_MAP(SubWin1, CDialog)
ON_WM_TIMER()
ON_WM_CLOSE()
END_MESSAGE_MAP() // SubWin1 message handlers DWORD WINAPI FunProc(LPVOID lpParameter)
{
MSG msg;
//DWORD id_thread = GetCurrentThreadId();
//printf("id_thread = %d\n", id_thread);
int i = 0;
BOOL stop_thread = FALSE;
while (!stop_thread)
{
//if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
//{
// if (msg.message == MY_MSG)
// break;
// TranslateMessage(&msg);
// DispatchMessage(&msg);
//}
if (GetMessage(&msg, 0, 0, 0)) {
switch (msg.message)
{
case MY_MSG:
stop_thread = TRUE;
break;
}
}
i++;
printf("i = %d\n", i);
Sleep(1000);
}
return 0;
} BOOL SubWin1::OnInitDialog()
{
CDialog::OnInitDialog(); // TODO: Add extra initialization here HANDLE hThread;
for (int i = 0; i < 3; i++) {
hThread = CreateThread(NULL, 0, FunProc, &i, 0, &dwThreadId[i]);
CloseHandle(hThread);
} SetTimer(0, 1000, NULL); //设置一秒刷新一次 return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
} void SubWin1::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
escape_time++;
if (escape_time > 10) {
for (int j = 0; j < 3; j++) {
if (!PostThreadMessage(dwThreadId[j], MY_MSG, 0, 0)) {
printf("post message failed,errno:%d\n", ::GetLastError());
}
}
EndDialog(0x00);
} CDialog::OnTimer(nIDEvent);
} void SubWin1::OnClose()
{
// TODO: Add your message handler code here and/or call default
for (int j = 0; j < 3; j++) {
if (!PostThreadMessage(dwThreadId[j], MY_MSG, 0, 0)) {
printf("post message failed,errno:%d\n", ::GetLastError());
}
} CDialog::OnClose();
}

这个程序起源于创建一个Dll带MFC库,前面有讲过这一章节内容。

C++第五十二篇 -- 多线程之消息传递的更多相关文章

  1. 第五十二篇、 OC获取视频的第一帧图片thumbnailImage

    获取视频的第一帧图片 有时候我们拍摄完视频后,希望获取一张图片当作这个视频的介绍,这个图片thumbnailImage可以从视频的第一帧获取到. 我们的思路是先获取视频的URL,然后初始化一个MPMo ...

  2. 转---秒杀多线程第十二篇 多线程同步内功心法——PV操作上 (续)

    PV操作的核心就是 PV操作可以同时起到同步与互斥的作用. 1.同步就是通过P操作获取信号量,V操作释放信号量来进行. 2.互斥其实就是,同时操作P操作,结束后进行V操作即可做到. Java上实现PV ...

  3. 第五十二篇 Linux相关——数据库服务MySQL

        No.1. MySQL基本操作 CentOS7默认安装mariadb数据库,先将其移除 移除命令:sudo yum -y remove mariadb-libs.x86_64 下载MySQL源 ...

  4. 第五十二篇:webpack的loader(三) -url-loader (图片的loader)

    好家伙, 1.什么是base64? 图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址. 这样做有什么意义呢?我们知道,我们所看到的网页上的每一个图片,都是需要 ...

  5. 《手把手教你》系列技巧篇(五十二)-java+ selenium自动化测试-处理面包屑(详细教程)

    1.简介 面包屑(Breadcrumb),又称面包屑导航(BreadcrumbNavigation)这个概念来自童话故事"汉赛尔和格莱特",当汉赛尔和格莱特穿过森林时,不小心迷路了 ...

  6. Spring Cloud第十二篇 | 消息总线Bus

    ​ ​本文是Spring Cloud专栏的第十二篇文章,了解前十一篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring ...

  7. 解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)

    解剖SQLSERVER 第十二篇   OrcaMDF 行压缩支持(译) http://improve.dk/orcamdf-row-compression-support/ 在这两个月的断断续续的开发 ...

  8. 第十二篇 SQL Server代理多服务器管理

    本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...

  9. 第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

随机推荐

  1. Go语言实现的23种设计模式之结构型模式

    摘要:本文主要聚焦在结构型模式(Structural Pattern)上,其主要思想是将多个对象组装成较大的结构,并同时保持结构的灵活和高效,从程序的结构上解决模块之间的耦合问题. 本文分享自华为云社 ...

  2. 干货!MySQL 的 InnoDB 存储引擎是怎么设计的?

    MySQL 里还有什么其他成员呢? 对于 MySQL,要记住.或者要放在你随时可以找到的地方的两张图,一张是 MySQL 架构图,另一张则是 InnoDB 架构图: 遇到问题,或者学习到新知识点时,就 ...

  3. 办公利器!用Python快速将任意文件转为PDF

    痛点: 相信大家都会遇到一种场景.老师/上司要求你把某个文件转为pdf,并且是一批(不止一个,一个的话手动就可以搞定),并且这种是枯燥无聊的工作,既没有什么技术含量又累. 试想一下,如果我把这些文件放 ...

  4. 5、rsync全网备份

    定时备份rsync(增量备份,无差异备份,daemon进程)+crontab,主要备份一些任务脚本和配置文件,如果此时有用户增加数据, 如果是增量备份的话不会备份下来,因为在备份的那一刻,数据已经被锁 ...

  5. 关于vim

    全部删除:按esc后,然后dG全部复制:按esc后,然后ggyG全选高亮显示:按esc后,然后ggvG或者ggVG 在win中使用<C-a>是全选,如果需要在vim中使用<C-a&g ...

  6. CRM的职能和主要构成模块探索

    CRM客户管理系统是随着互联网的快速发展和信息技术的进步而发展起来的,是企业管理客户关系.优化业务流程的首选.客户关系管理可以存储企业获得的客户信息,方便业务人员随时查看和了解客户需求:客户关系管理可 ...

  7. Spring缓存的注解关键词解释

    Spring缓存的注解关键词解释 @Cacheable支持缓存 @Cacheable可以标记在一个方法上,也可以标记在一个类上. 1.当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表 ...

  8. springboot 使用yml配置文件自定义属性

    springboot 中在application.yml文件里自定义属性值,配合@Value注解可以在代码中直接取到相应的值,如在application.yml中添加 mqtt: serverURI: ...

  9. pip 下载时出现问题TypeError: unsupported operand type(s) for -=: 'Retry' and 'int'

    我这里解决就是更新下载源,马德,中科的源居然不够快,我就只能换源了,一换就成功了 1.一次性(临时使用): 可以在使用pip的时候加参数-i https://pypi.tuna.tsinghua.ed ...

  10. Redis为什么变慢了?常见延迟问题定位与分析

    Redis作为内存数据库,拥有非常高的性能,单个实例的QPS能够达到10W左右.但我们在使用Redis时,经常时不时会出现访问延迟很大的情况,如果你不知道Redis的内部实现原理,在排查问题时就会一头 ...