操作系统——MFC实现进程创建和通信4
引入
我接着上篇博客讲,如果没有构建项目的童鞋请移步到操作系统——MFC实现进程创建和通信1
用PostMessage实现通信请移步到操作系统——MFC实现进程创建和通信2
用CopyDATA消息实现进程间通信请到操作系统——MFC实现进程创建和通信3
这篇博客使用共享内存的方式实现进程间通信,这适用于有很多内容要传输的情况,这种方法没有前两种方法安全,因为存在着内存交互有临界资源,可能出现死锁问题(用户自己慢慢发是不存在同时访问锁住的,除非你同时点击的速度到了ms级(* _ *),所以这里我就没有通过PV操作设置同步)
通过共享内存实现通信
通信原理
共享内存就是允许两个不相关的进程访问同一个逻辑内存,共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。
不同进程之间共享的内存通常为同一段物理内存。进程可以将同一段物理内存连接到他们自己的地址空间中,所有的进程都可以访问共享内存中的地址。如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。
优点:共享内存进行进程之间的通信是非常方便的,而且函数的接口也比较简单,数据的共享还使进程间的数据不用传送,而是直接访问内存,加快了程序的效率。
缺点:共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之前,并无自动机制可以阻止第二个进程开始对它进行读取,所以我们通常需要用其他的机制来同步对共享内存的访问,使用信号量机制实现PV操作使用不当,易产生死锁。
1、MainProcessDlg.cpp中添加共享内存
在MainProcessDlg.cpp中的初始化函数**OnlinitDialog()**添加共享内存
// 在窗口创建的时候创建共享内存//在构造函数中创建共享内存,名称为"Data Mutex"HANDLE hFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 1000000, _T("Data Mutex"));if (!hFile)//判断是否成功创建{AfxMessageBox(_T("共享内存创建失败!"));return TRUE;}if (GetLastError() == ERROR_ALREADY_EXISTS){AfxMessageBox(_T("创建共享内存成功,准备写入数据"));return TRUE;}LPBYTE lpData = (LPBYTE)MapViewOfFile(hFile, FILE_MAP_WRITE, 0, 0, 0);//写模式访问共享内存if (!lpData){AfxMessageBox(_T("写入数据失败"));CloseHandle(hFile);return TRUE;}TCHAR buf[1024] = _T("这是要写入的内容");//要写入的内容memcpy(lpData, buf, sizeof(buf));//写入
共享内存的生命周期可以不同,这里我直接在创建Main窗口的时候分配一段内存用于共享访问,在构造函数中添加代码,创建为逻辑地址从0到1000000的共享内存;在创建内存的时候最好同时进行写入测试,因为可能分配不到内存,进行一下测试是比较好的(100万也才不到2kb,一个内存块就有4k了,嫌不够的童鞋可以多写几个0,或者写16进制0x…)
2、在MainProcessDlg.cpp中修改点击事件
修改写内存文件Button
在资源视图中双击写内存文件Button跳转到点击事件中重写函数。
void CMFCApplication1Dlg::OnBnClickedButton1()
{HANDLE hFile = OpenFileMapping(FILE_MAP_WRITE, FALSE, _T("Data Mutex"));if (!hFile){AfxMessageBox(_T("打开共享内存失败"));return;}LPBYTE lpData = (LPBYTE)MapViewOfFile(hFile, FILE_MAP_WRITE, 0, 0, 0);//写模式访问共享内存if (!lpData){AfxMessageBox(_T("写入数据失败"));CloseHandle(hFile);return;}CString strtext;GetDlgItemText(IDC_EDIT1, strtext);//获取EDIT控件内容TCHAR buf[1024];wcscpy_s(buf, strtext);//格式转换memcpy(lpData, buf, sizeof(buf));//写入共享内存
}
修改读内存文件Button
在资源视图中双击读内存文件Button跳转到点击事件中重写函数。
void CMFCApplication1Dlg::OnBnClickedOk5()
{HANDLE hFile = OpenFileMapping(FILE_MAP_READ, FALSE, _T("Data Mutex"));if (!hFile){AfxMessageBox(_T("打开共享内存失败"));return;}LPBYTE lpData = (LPBYTE)MapViewOfFile(hFile, FILE_MAP_READ, 0, 0, 0);if (!lpData){AfxMessageBox(_T("读取共享内存失败"));CloseHandle(hFile);return;}TCHAR buf[1024];memset(buf, 0, sizeof(buf));memcpy(buf, lpData, sizeof(buf));SetDlgItemText(IDC_EDIT1, buf);if (lpData)UnmapViewOfFile(lpData);if (hFile)CloseHandle(hFile);
}
3、在ChildProcessDlg.cpp中修改点击事件
修改写内存文件Button
在资源视图中双击写内存文件Button跳转到点击事件中重写函数。
void CMFCApplication1Dlg::OnBnClickedButton1()
{HANDLE hFile = OpenFileMapping(FILE_MAP_WRITE, FALSE, _T("Data Mutex"));if (!hFile){AfxMessageBox(_T("打开共享内存失败"));return;}LPBYTE lpData = (LPBYTE)MapViewOfFile(hFile, FILE_MAP_WRITE, 0, 0, 0);//写模式访问共享内存if (!lpData){AfxMessageBox(_T("写入数据失败"));CloseHandle(hFile);return;}CString strtext;GetDlgItemText(IDC_EDIT1, strtext);//获取EDIT控件内容TCHAR buf[1024];wcscpy_s(buf, strtext);//格式转换memcpy(lpData, buf, sizeof(buf));//写入共享内存
}
修改读内存文件Button
在资源视图中双击读内存文件Button跳转到点击事件中重写函数。
void CMFCApplication1Dlg::OnBnClickedOk5()
{HANDLE hFile = OpenFileMapping(FILE_MAP_READ, FALSE, _T("Data Mutex"));if (!hFile){AfxMessageBox(_T("打开共享内存失败"));return;}LPBYTE lpData = (LPBYTE)MapViewOfFile(hFile, FILE_MAP_READ, 0, 0, 0);if (!lpData){AfxMessageBox(_T("读取共享内存失败"));CloseHandle(hFile);return;}TCHAR buf[1024];memset(buf, 0, sizeof(buf));memcpy(buf, lpData, sizeof(buf));SetDlgItemText(IDC_EDIT1, buf);if (lpData)UnmapViewOfFile(lpData);if (hFile)CloseHandle(hFile);
}
运行结果
注
点击事件的处理是一样的,都是先进行安全性检查,能打开内存文件并且lpData已经分配了的话,就可以开始读写操作了,对于用户级的操作我都没有加上信号量的控制,上面也说了基本不可能出现死锁问题,具体的PV操作我将在下次博客中再描述(线程创建与线程同步问题)。
这次对于进程通信问题就到这里了,进程用管道通信,我创建管道之后在读取管道文件的时候有忙等待问题,经常锁死在那,就不写出来丢人了,啥时候有时间研究一下再来分享给大家。大家如果有好的思路请在下面留言(~ _ ~)
操作系统——MFC实现进程创建和通信4相关推荐
- Linux进程的创建和父子进程同步,操作系统实验报告_Linux进程创建与通信.doc
操作系统实验报告_Linux进程创建与通信 2011-2012学年第一学期 专 业: 班 级: 学 号: 姓 名:提交日期:2011年11月实验二 Linux进程创建与进程通信 [实验目的 1. 熟悉 ...
- linux系统编程之进程概念(操作系统---管理,进程创建,进程状态,进程优先级, 环境变量,程序地址空间,进程O(1)调度方法)
系统编程: 进程概念->进程控制->基础IO->进程间通信->进程信号->多线程 进程概念 冯诺依曼体系结构----现代计算机硬件体系结构 冯诺依曼体系结构----现代计 ...
- 操作系统——实验贰——进程通信(一)管道及共享内存
一. 实验目的 熟悉并掌握管道机制,并实现进程间通信 熟悉并掌握共享内存机制,并实现进程间通信 二. 实验内容 任务一: (1)阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析 ...
- 模拟进程创建、终止、阻塞、唤醒原语_轻松搞定进程原理
进程简介 并发和并行 并发:在一个时间段中多个程序都启动运行在用一个处理机中 并行:两个进程分别由不同的CPU管理执行,两个进程不抢占CPU的资源,且可以同时运行,叫做并行 区别在于是否同时 多进程的 ...
- mfc编程vc6.0实现进程的创建和通信_免费送书:windows黑客编程技术详解
01 书怎么送 点赞并留言,关注在下面的公众号后台回复「抽奖」,弹出小程序后点击参与. 开奖时间是 7 月 7 号 20:00 ,一定要留意微信消息,如果你中奖了,请尽快在中奖页面提交收件人信息并备注 ...
- MFC(进程间的通信,孙鑫C++第十七讲笔记整理)
有四种方法 1.剪贴板 a.创建个ClipBoard的对话框应用程序,加两EditBox和两个Button发送接收. b.具体代码: 发送端代码: if(OpenClipboard()) ...
- linux 实验2 进程创建,实验2Linux进程控制与通信
实验2Linux进程控制与通信 实验 2 Linux 进程控制与通信1. 实验目的(1 ) 进一步认识并发执行的概念,认识父子进程及进程创建原理:(2 ) 了解 Linux 系统中进程通信的基本原理. ...
- 模拟进程创建、终止、阻塞、唤醒原语_操作系统基础8-进程及进程控制
进程(Process) 的定义 从不同的角度,进程可以有不同的定义,传统典型的定义: 进程是程序的一次执行过程. 或者:一个正在执行的程序的实例 进程是一个程序及其数据在处理机上顺序执行所发生的活动 ...
- 4 操作系统第二章 进程管理 进程控制、通信
文章目录 1 进程控制 1.1 进程控制 1.2 进程控制实现 1.3 进程创建 1.4 进程终止 1.5 进程阻塞与唤醒 1.6 进程切换 1.7 进程控制小结 2 进程通信 2.1 共享通信 2. ...
最新文章
- 64位linux下was宕机,was7经常自动宕机,前方告急,工程师面临崩溃.小弟跪上
- 细粒度图像分类_支付宝AI大幅提升细粒度图像分类识别精度:一眼看穿万物细微差异...
- ES6---箭头函数()={} 与function的区别(转载)
- 递归和分治思想及其应用
- 计算机三级教材重点网络技术,2020年计算机三级网络技术知识点梳理:身份认证...
- 通过C#中的在线文件自动更新应用程序
- 如何配置php session使用redis集群
- 机器学习笔记 - 使用Keras + Unet 进行图像分割
- 电脑维修常用检修软件技术
- PSI(隐私集合求交集)的几类基础思想
- 【English】【托业】【四六级】写译高频词汇
- 计算机主机和音箱的接口电路,Zigbee协议与USB主机无线音箱电路设计
- 用python编写猜数字游戏
- 将图片转换成caffe的数据格式
- C#轻松创建ModbusTCP服务器【Slave】,实现工业数据交换接口。
- android 解决按钮、imageView 背景图片拉伸变大的问题
- 首页大广告展示——淘淘商城(十六)
- 2018年9月份面试小记
- html css 布局_创建有吸引力HTML CSS动漫主题网站布局
- linux运维工程师毕业设计,论文写作:运维工程师毕业论文怎么写?
热门文章
- 从硬件到软件,苹果一直坚持的造车梦....
- 桥墩水流绕流阻力问题计算
- WMI权限问题:Access is denied, please check whether the [domain-username-password] ..
- VHDL实现USART
- SpringMVC整合mybatis(终结版)
- 汇编语言-int指令
- 南宁装修工长带队,价格公道不乱增加项目
- 装配图中齿轮的画法_机械制图教程(8.2)装配图的规定画法和特殊画法
- STM32F1串口最高波特率问题
- JSON字符串与protobuf互转