C++第五十二篇 -- 多线程之消息传递
主线程向子线程发送消息
参考链接: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++第五十二篇 -- 多线程之消息传递的更多相关文章
- 第五十二篇、 OC获取视频的第一帧图片thumbnailImage
获取视频的第一帧图片 有时候我们拍摄完视频后,希望获取一张图片当作这个视频的介绍,这个图片thumbnailImage可以从视频的第一帧获取到. 我们的思路是先获取视频的URL,然后初始化一个MPMo ...
- 转---秒杀多线程第十二篇 多线程同步内功心法——PV操作上 (续)
PV操作的核心就是 PV操作可以同时起到同步与互斥的作用. 1.同步就是通过P操作获取信号量,V操作释放信号量来进行. 2.互斥其实就是,同时操作P操作,结束后进行V操作即可做到. Java上实现PV ...
- 第五十二篇 Linux相关——数据库服务MySQL
No.1. MySQL基本操作 CentOS7默认安装mariadb数据库,先将其移除 移除命令:sudo yum -y remove mariadb-libs.x86_64 下载MySQL源 ...
- 第五十二篇:webpack的loader(三) -url-loader (图片的loader)
好家伙, 1.什么是base64? 图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址. 这样做有什么意义呢?我们知道,我们所看到的网页上的每一个图片,都是需要 ...
- 《手把手教你》系列技巧篇(五十二)-java+ selenium自动化测试-处理面包屑(详细教程)
1.简介 面包屑(Breadcrumb),又称面包屑导航(BreadcrumbNavigation)这个概念来自童话故事"汉赛尔和格莱特",当汉赛尔和格莱特穿过森林时,不小心迷路了 ...
- Spring Cloud第十二篇 | 消息总线Bus
本文是Spring Cloud专栏的第十二篇文章,了解前十一篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring ...
- 解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)
解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译) http://improve.dk/orcamdf-row-compression-support/ 在这两个月的断断续续的开发 ...
- 第十二篇 SQL Server代理多服务器管理
本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...
- 第十二篇 Integration Services:高级日志记录
本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...
随机推荐
- 一、DNS服务器的搭建
一.介绍 DNS服务:域名解析 将域名解析ip地址 DNS服务器的功能– 正向解析:根据注册的域名查找其对应的IP地址– 反向解析:根据IP地址查找对应的注册域名,不常用 所有完整的域名都要以点结 ...
- Kafka 总结学习
Kafka Need No Keeper 最近在鹅厂工作中不断接触到Kafka,虽然以前也使用过,但是对其架构和发展过程总是模模糊糊,所以在回学校准备末考的时候找些资料总结一下. Kafka Need ...
- 关于equals()和hashcode()的一些约定
本文章主要讨论和回答一下几个问题: equals()的四大特性 equals()和hashcode()之间的关系,为什么我们经常说这两个方法要么都重写,要么都不重写? HashMap.HashSet等 ...
- MIT6.828 Lab3 User Environments
Lab3 这个实验分成了两个大部分. 1. PartA User Environments and Exception Handling kernel使用Env这个数据结构来trace每一个user ...
- JDK1.8 ArrayList 源码解析
源码的解读逻辑按照程序运行的轨迹展开 Arraylist的继承&实现关系 打开ArrayList源码,会看到有如下的属性定义, ArrayList中定义的属性 /** * Default in ...
- Spring中这么重要的AnnotationAwareAspectJAutoProxyCreator类是干嘛的?
大家好,我是冰河~~ 停更了很久的[Spring注解系列]专题,终于重新更新了,我们还是接着之前的文章继续往下更新.在<[Spring注解驱动开发]二狗子让我给他讲讲@EnableAspectJ ...
- 解决Windows Server 2012 在VMware ESXi中经常自动断网问题
最近一些开发人员反映他们使用的 Windows server2012 R2 虚拟机过段时间就远程连接不上了,ping也不通(已关闭防火墙),我们登录ESXi发现,Windows Server 的网络图 ...
- Java:Java单例中的懒汉和饿汉模式
1.懒汉模式 懒汉模式:在类加载的时候不被初始化,懒汉式是延时加载,他是在需要的时候才创建对象. public class JdbcUtil { //定义私有的引用 private static Jd ...
- SpringMVC(2)经典的HelloWorld实现
我机器的开发环境为: Ubuntu12.04(不同操作系统对本系列项目没有影响): 开发工具:Eclipse For JavaEE: 数据库:MySql5.5.35; 运行环境:TomCat V7.0 ...
- elf文件结构解读以及plt节got节的理解
前言: 熟悉elf文件结构是一件很不错的事,因为安卓中的so加固以及修复都是需要这些知识的,包括pwn里面的rop之类的,也都是 和got节,plt节息息相关的,个人建议是在搞懂elf文件结构后,自己 ...