【C/C++实现进程间通信 一】共享内存方式

文章目录

  • 前情回顾
  • 思路
  • 源码
      • Publisher.cpp
      • Subscriber.cpp
  • 效果

前情回顾

上一期已经讲解过了进程的相关概念以及进程间通信的实现原理,下面仅展示共享内存方式实现进程间通信的相关代码。

思路

/* 本项目主要用于对同主机上以共享内存方式进行进程间通信的测试 。
1.包含一个外部程序 publisherDemo.exe 以及 subscriberDemo.exe。
2.publisherDemo 主要功能是实现定时信息发布,并将信息发送到共享内存。
3.subscriberDemo 主要功能是实现访问指定共享内存,对publisherDemo.exe进程发布的信息进行捕获。
4.此外,本项目还利用信号量机制实现了进程间的同步发送与接收的功能。
*/

源码

环境:Windows 64位 + QtCreator
涉及到一些WINAPI中的函数,具体函数解析可自行参考WINAPI官方文档

Publisher.cpp

#include <QCoreApplication>
#include <Windows.h>
#include <iostream>
using namespace std;#define BUF_SIZE 4096HANDLE g_EventRead;		// 读信号灯
HANDLE g_EventWrite;	// 写信号灯
// 定义共享数据
char szBuffer[] = "Hello, shared memory!";
/* 读取con1串口的线程 */
DWORD __stdcall WriteThread(const LPVOID lp)
{while (true){WaitForSingleObject(g_EventWrite, INFINITE); // 等待读数据的信号// 将数据拷贝到共享内存strcpy((char*)lp, szBuffer);cout << "数据发送成功!等待订阅端接受:" << (char*)lp << endl;Sleep(1000);SetEvent(g_EventRead);ResetEvent(g_EventWrite);}return DWORD();
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 创建共享文件句柄HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,               // 物理文件句柄  NVALID_HANDLE_VALUE  则创建一个进程间共享的对象NULL,                               // 默认安全级别PAGE_READWRITE,                     // 可读可写0,                                  // 高位文件大小BUF_SIZE,                           // 低位文件大小L"ShareMemoryPDU"                   // 映射文件名,即共享内存的名称);if (0 == hMapFile){return 0;}// 映射缓存区视图 , 得到指向共享内存的指针// 将hFileMapping共享内存衍射到本进程的地址空间中LPVOID lpBase = MapViewOfFile(hMapFile,                           // 共享内存的句柄FILE_MAP_ALL_ACCESS,                // 可读写许可0,0,BUF_SIZE);if (0 == lpBase){return 0;}g_EventRead = CreateEventW(NULL, TRUE, FALSE, TEXT("EventRead"));if (nullptr == g_EventRead){return 0;}g_EventWrite = CreateEventW(NULL, TRUE, TRUE, TEXT("EventWrite"));if (nullptr == g_EventRead){return 0;}HANDLE handle = CreateThread(NULL, 0, WriteThread, lpBase, 0, NULL);WaitForSingleObject(handle, INFINITE);// 解除文件映射UnmapViewOfFile(lpBase);// 关闭内存映射文件对象句柄CloseHandle(hMapFile);return 0;return a.exec();
}

Subscriber.cpp

#include <QCoreApplication>
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;#define BUF_SIZE 4096HANDLE g_EventRead;		// 读信号灯
HANDLE g_EventWrite;	// 写信号灯DWORD __stdcall ReadThread(const LPVOID lp)
{while (true){WaitForSingleObject(g_EventRead, INFINITE); // 等待读数据的信号// 将共享内存数据拷贝出来char szBuffer[BUF_SIZE]{ 0 };strcpy_s(szBuffer, (char*)lp);std::cout << "订阅端读取数据成功!:" << szBuffer << endl;ResetEvent(g_EventRead); /* 将读取信号关闭  */SetEvent(g_EventWrite);}
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 打开共享的文件对象HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, L"ShareMemoryPDU");if (0 == hMapFile){// 打开共享内存句柄失败std::cout << "打开共享内存失败!" << endl;return 0;}LPVOID lpBase = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);if (0 == lpBase){return 0;}g_EventRead = CreateEventW(NULL, TRUE, FALSE, TEXT("EventRead"));if (nullptr == g_EventRead){return 0;}g_EventWrite = CreateEventW(NULL, TRUE, TRUE, TEXT("EventWrite"));if (nullptr == g_EventRead){return 0;}HANDLE handle = CreateThread(NULL, 0, ReadThread, lpBase, 0, NULL);if (0 == handle){return 0;}WaitForSingleObject(handle, INFINITE);// 解除文件映射UnmapViewOfFile(lpBase);// 关闭内存映射文件对象句柄CloseHandle(hMapFile);return a.exec();
}

注:以上程序运行顺序应该为:先启动Subscriber.exe,再启动Publisher.exe。

效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/3675.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

路由基础静态路由

路由基础&静态路由 一、路由器基本原理1.1、路由器基本概述1.2、LAN和广播域1.3、路由选路1.3.1、路由器转发数据包1.3.2、IP路由表1.3.3、建立路由表1.3.4、最长匹配原则1.3.5、路由优先级1.3.6、路由度量1.3.7、等价路由 1.4、总结 二、静态路由基础2.1、静态路由配置2.2…

Spring Boot 中的 EhCacheCacheManager 是什么,原理,如何使用

Spring Boot 中的 EhCacheCacheManager 是什么&#xff0c;原理&#xff0c;如何使用 前言 在现代化的应用程序中&#xff0c;缓存是提高性能的关键所在。缓存可以降低数据库的负载&#xff0c;提高响应速度&#xff0c;减少资源消耗。Spring Boot提供了多种缓存管理器&#…

【C++】模板进阶

目录 1.非类型模板参数2.模板的特化2.1概念2.2 函数模板特化2.3 类模板特化2.3.1 全特化2.3.2 偏特化2.3.3 应用 3.模板分离编译4.模板总结 1.非类型模板参数 模板参数可分为类型形参和非类型形参 类型形参&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename…

百度编辑器(Ueditor)视频上传到阿里云 + 预览不支持FLASH问题解决 + 输入框不展示视频播放页面问题解决

目前需求方提出的问题是以下四个&#xff1a; 1.百度编辑器&#xff08;Ueditor&#xff09;视频上传到阿里云 2.解决不支持FLASH问题 3.视频上传后可以预览 4.修改视频封面 看一下原始的功能是什么样的 上传视频&#xff1a; 视频上传完成 上传视频保存的路径&#xff1…

session和token

一、使用HttpSession接口的setAttribute()方法将cookie保存到客户端的浏览器中 二、单点登录逻辑 1、客户端服务有一个过滤器&#xff0c;先判断有没有重定向回来的token值&#xff08;过去session用&#xff0c;没有也没关系&#xff09; 2、客户端过滤器再判断session中有没…

React V6分环境打包

功能背景 例如想要在react也要实现不同环境使用不同的api接口地址这样的想法&#xff0c;那么就需要根据命令自动区分环境了。 代码实现 比如我这又三种环境&#xff0c;那么创建三个文件&#xff0c;如图&#xff1a; 分别是dev:开发环境&#xff0c;formal&#xff1a;UAT环境…

Flink中FileSink的使用

在Flink中提供了StreamingFileSink用以将数据流输出到文件系统. 这里结合代码介绍如何使用FileSink. 首先FileSink有两种模式forRowFormat和forBulkFormat public static <IN> DefaultRowFormatBuilder<IN> forRowFormat(final Path basePath, final Encoder<IN…

Ubuntu的USB相关操作

这里写目录标题 0.信息查看1. 串口设备设置2. 串口调试助手 0.信息查看 指令lsusb输出Bus 004 Device 002: ID 05e3:0620 Genesys Logic, Inc. USB3.2 Hub Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 006: ID 5986:115f Acer, Inc Integ…

ShaderGraph制作“红旗迎风飘扬”效果(Unity2019版)

文章目录 零、准备“旗面”游戏物体一、核心1 模仿旗面的“起伏”二、核心2 让旗面的“吹动”起来三、几点改进A、 “旗面的摆动幅度”改进01&#xff1a;前后对称B、 “旗面的摆动幅度”改进02&#xff1a;从左往右逐渐增大C、 “旗面的飘动方向”改进01&#xff1a;只让在X轴…

webassembly简单Demo——hello world

参考官网 Emscripten Tutorial 一、创建C/C文件 hello.c #include <stdio.h>int main() {printf("hello, world!\n");return 0; } 二、编译成html 命令行切到hello.c目录下&#xff0c;执行如下命令(注意需要em的环境变量&#xff0c;参考&#xff1a;emsr…

CVE-2023-34541 LangChain 任意命令执行

漏洞简介 LangChain是一个用于开发由语言模型驱动的应用程序的框架。 在LangChain受影响版本中&#xff0c;由于load_prompt函数加载提示文件时未对加载内容进行安全过滤&#xff0c;攻击者可通过构造包含恶意命令的提示文件&#xff0c;诱导用户加载该文件&#xff0c;即可造成…

续篇-docker篇: 优势与安装方式 及基础指令整合

目录 1. 前言简介: 1.1 docker的优势: 1.2 docker的简易理解 2. 指令安装 2.1 安装yum的插件 ps: 提示没权限加上sudo即可 root用户不用 2.2 设置yum仓库地址 ps: 设置多个镜像仓库, 不设置可能会下载变慢 ps: 如图所示 2.3 更新缓存 2.4 安装docker 2.5 查看do…