Windows进程间通讯(IPC)----消息队列
消息队列
windows系统是通过消息驱动的,每移动一下鼠标,点击一下屏幕都会产生一个消息。这些消息会先被放在windows的一个系统消息队列(先进先出)中,windows系统会为每一个GUI线程创建一个线程消息队列,然后系统会从系统消息队列中取出一个消息放到对应的线程消息队列中。之后通过消息循环从线程消息队列中取出消息分发派遣到对应的窗口的窗口过程中。

线程消息队列是如何创建的
系统消息队列是由windows操作系统默认创建的,而对于普通的线程而言是没有线程消息队列的。线程刚创建时为普通线程,其KTHREAD.ServiceTable字段指向的是KerServiceDescriptorTable(SSDT)表,这个表包含的是ntoskrnl.exe服务函数,都是一些非GUI函数。如果我们在线程中调用第一个Windows的GUI函数时,线程的KTHREAD.ServiceTable字段会指向KerServiceDescriptorTable(Shadow SSDT)表,这个表不光包含ntoskrnl.exe服务函数还包含win32k.sys服务函数,后者包含了GUI函数。而且会分配空间为KTHREAD.win32Thread指针分配空间,由此指针就可以找到相应的线程消息队列。
利用消息队列进行IPC
因为线程消息队列是在内核中的,所以可以通过消息队列进行进程间通信(IPC)。当然进行进程间通讯的两个进程必须有GUI线程才行,因为只有GUI线程才有线程消息队列。
消息类型
系统保留从0x0000---0x03ff(WM_USER-1)的值用于系统定义的消息,而用户自定义消息的范围为0x0400(WM_USER)---0x7fff。
发送消息
消息队列中的消息对应一个消息结构MSG,包含了消息的各个信息。我们在利用消息进行进程间通讯时是通过WPARAM和LPARAM传递讯息的。
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
DWORD lPrivate;
} MSG, *PMSG, *NPMSG, *LPMSG;
我们可以通过SendMessage或PostMessage发送消息,但是SendMessage直接将消息发送到对应的窗口过程中并不放在消息队列里,所以我们要想通过消息队列实现IPC应该使用PostMessage。
PostMessageA可以将消息发送到窗口句柄hWnd对应的线程消息队列中,PostThreadMessageA可以将消息发送到线程句柄hThread对应的消息队列中。(这里注意hWnd窗口句柄是属于用户对象的句柄一般通过FindWindow函数获取,而hThread是内核对象的句柄一般通过跨进程共享内核对象完成)
BOOL PostMessageA(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
获取消息
获取消息有一般使用PeekMessage或GetMessage。
PeekMessage可以检索当前调用线程的线程消息队列中指定的消息,并不指定检索后如何处理线程队列中的消息(删除还是保留)。
BOOL PeekMessageA(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
);
GetMessage和PeekMessage一样,只不过其会在检索到消息后直接将消息从对应的线程消息队列中删除。
BOOL GetMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
);
Windows进程间通讯(IPC)----消息队列的更多相关文章
- High Performance Networking in Google Chrome 进程间通讯(IPC) 多进程资源加载
小结: 1. 小文件存储于一个文件中: 在内部,磁盘缓存(disk cache)实现了它自己的一组数据结构, 它们被存储在一个单独的缓存目录里.其中有索引文件(在浏览器启动时加载到内存中),数据文件( ...
- Android AIDL 进行进程间通讯(IPC)
编写AIDL文件时,需要注意: 1.接口名和aidl文件名相同. 2.接口和方法前不用加访问权限修饰符 (public.private.protected等,也不能用final.static). 3. ...
- QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开 本文地址:h ...
- Windows进程间通讯(IPC)----WM_COPYDATA
WM_COPYDATA通讯思路 通过向其他进程的窗口过程发送WM_COPYDATA消息可以实现进程间通讯. 只能通过SendMessage发送WM_COPYDATA消息,而不能通过PostMessag ...
- Windows进程间通讯(IPC)----共享内存
Windows中同一个EXE文件多次加载过程 Windows中EXE文件加载是基于内存映射文件的. 当EXE文件第一次被加载. 首先系统会先创建一个进程内核对象,并创建一个新的进程地址空间. 系统调用 ...
- Windows进程间通讯(IPC)----内存映射文件
内存映射文件原理 内存映射文件是通过在虚拟地址空间中预留一块区域,然后通过从磁盘中已存在的文件为其调度物理存储器,访问此虚拟内存空间就相当于访问此磁盘文件了. 内存映射文件实现过程 HANDLE hF ...
- 服务 远程服务 AIDL 进程间通讯 IPC
Activity aidl接口文件 package com.bqt.aidlservice; interface IBinderInterface { /* 更改文件后缀为[.aidl]去掉 ...
- Windows进程间通讯(IPC)----管道
管道的分类 管道其实际就是一段共享内存,只不过Windows规定需要使用I/O的形式类访问这块共享内存,管道可以分为匿名管道和命名管道. 匿名管道就是没有名字的管道,其支持单向传输数据,如果需要双向传 ...
- Windows进程间通讯(IPC)----信号量
线程同步内核对象 操作系统进行进程间同步是利用信号量机制.对于windows系统而言,可以利用一些内核对象进行线程同步,因为这些内核对象可以命名并且属于系统内核,所以可以支持不同进程间的线程同步进而实 ...
随机推荐
- 热门跨平台方案对比:WEEX、React Native、Flutter和PWA
本文主要对WEEX.React Native.Flutter和PWA几大热门跨平台方案进行简单的介绍和对比.内容选自<WEEX跨平台开发实战> (WEEX项目负责人力荐,从入门到实战,教你 ...
- Python打包之setuptools
参考链接1 参考链接2 参考链接3 一.setuptools介绍 Setuptools是Python Distutils的加强版,使开发者构建和发布Python包更加容易,特别是当包依赖于其他包时.用 ...
- 【PAT甲级】1119 Pre- and Post-order Traversals(前序后序转中序)
[题目链接] [题意] 根据二叉树的前序和后序序列,如果中序序列唯一,输出Yes,如果不唯一输出No,并输出这个中序序列. [题解] 众所周知,二叉树是不能够根据前序和中序建立的,为什么呢?首先需要明 ...
- 2、Spring教程之HelloSpring
导入Jar包 注 : spring 需要导入commons-logging进行日志记录 . 我们利用maven , 他会自动下载对应的依赖项 . <dependency> <grou ...
- sqli-labs系列——第二关
less2 and 1=1有回显,and 1=2无回显,为数值型注入 order by 4–+报错,有3行 查询数据库名 ?id=0' union select 1,(select group_con ...
- springBoot高级:自动配置分析,事件监听,启动流程分析,监控,部署
知识点梳理 课堂讲义 02-SpringBoot自动配置-@Conditional使用 Condition是Spring4.0后引入的条件化配置接口,通过实现Condition接口可以完成有条件的加载 ...
- 从阿里云迁移分布式redis实例到华为云解决方案(详细)
如果要换多数是经济因素啦- 一. 准备工作 先在华为云上买一台redis数据库,配置一定要注意多数要保持一致,至于4.0还是5.0倒问题不大亲测兼容 可用区要找现有ECS云主机中的相同的机器.记下:这 ...
- FastDFS一步步搭建存储服务器
一:FastDFS简介 1:FastDFS简介 FastDFS是一个开源的轻量级分布式文件系统,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适 ...
- Go-06-数据类型、常量、运算符
数据类型转换 Go语言采用数据类型前置加括号的方式进行类型转换,格式如:T(表达式).T表示要转换的类型:表达式包括变量.数值.函数返回值等. var a int =100 b := float(a) ...
- 002-Java的标识符和关键字
目录 一.标识符 1.什么是标识符 2.标识符的命名规则 3.标识符的命名规范 二.关键字 1.什么是关键字 2.Java中的关键字 一.标识符 1.什么是标识符 标识符就是程序员自己规定的代表一 ...