当前课程知识点:基于Linux的C++ > 第十三讲 进程编程 > 13.10 进程间通信(四) > LinuxCPP1310
接下来就是映射内存 memory map
映射内存和共享内存非常得类似
它的基本机制其实是一样的
唯一的差别就是映射内存
它将会将一个文件
映射到我们这个内存区域里边
文件呢会被分割成页面的大小
映射进来
这个时候就可以向内存数据一样
来操纵这个文件
这个时候效率会更高
使用mmap()完成这个基本的映射
这里边有一些参数
Addr就表示映射目的地的地址
参数length就表示映射内存的大小
prot表示的就是映射内存的保护权限
读权限 写权限等等执行权限
flags就是映射的时候它的附加的选项
fd就是待映射文件的文件描述符
offset就是你指定映射的那个文件
在那个文件中的偏移量
从什么地方开始映射 很典型
当你文件很大的时候只能映射一部分
这个offset就有用了
函数返回值呢
返回的就是映射文件映射以后
在内存中的基地址
如果失败了当然就会返回失败的标记
后来你又不用这个映射内存
那么你就可以调用munmap()
释放这个映射内存
传一个地址进去
传这个映射内存的长度尺寸
就OK了
映射的内存如果想要同步
就可以调用msync()这个函数
完成它的同步动作
我们看读写映射内存的实例
在这个程序里
我们定义一个常量mapped_size
4096个字节
实际映射的数目
是映射的尺寸除以整数的尺寸
我们实际上就将映射1024个整数(注:int尺寸为32位)
刚好是一个内存页面 就这个意思
主函数 我们首先打开一个文件
作为内存映射的对象
我们要确保这个文件的尺寸
足够存储1024个整数
所以我们定位到文件的结尾
然后朝里边写一个空白
重新再定位到开头
我们只是write() 写进去
就保证这个文件会构造出来
4096个字节
这个代码做的就是这个事
我们打开这个文件作为映射内存的对象
然后确保文件的尺寸
能够容纳1024个整数 就4096个字节
一开始把这个文件开出来
否则的话你一开始创建这个文件
数据是没有的 它的文件尺寸是0
你想映射的话 映射就不会成功
因为尺寸不够 尺寸不满足它的要求
所以我们要一开始
就把这个文件构造出来
有4096个字节 做的就这个事
然后我们会把它
文件指针定位到文件的开头
再然后我们就调用mmap()
去映射这个文件
把它映射到内存里
然后就可以用base这个指针来访问它
我们把它转型成指向整数的指针
来访问它 对吧
我们按照这个模式映射
映射完以后
那个文件描述符就可以关掉了 不用了
我们就可以使用映射内存的指针
基地址那个指针来操纵它就OK了
现在我们fork一个子进程
fork一个子进程以后
我们在子进程里边
向这个映射内存里写数据
这个映射内存的写数据
它就会反映到我们的磁盘文件里
那个磁盘文件里
这些数据就会被写进去
我一个for循环
从头开始写1024个整数
第一个整数是0 第二个整数是1
第三个整数是2
最后一个整数是1023
我就写这么多个整数
把它写进去 就完了
这就是一个for循环
因为整个循环内部要做的事情
都在循环头部做完了
所以循环体本身是空的
做完了以后 我们就munmap()
取消这个映射
在父进程里边呢
我们首先睡10秒钟
等到那边都写完了
我们就写一个for循环
一个一个地从这个文件中
把这个数据读出来 就完事了
因为这个文件映射是在我们构造
这个子进程之前就做完了
所以这个映射的内存
自动地被父进程和子进程所共享
父进程和子进程就可以使用
那个映射的内存来交换数据了
这个显然要比使用管道要方便一些 为啥
因为第一 它可以和文件挂在一块
第二 这个尺寸你可以定得很大
当你要传较大量数据的时候
这个技术就有用了
刚才不说了嘛 那个管道那个东西
它一般的数据传输就只有一个页面
管道的数据传输 它是受限的
容量是有限的
而我们映射内存 只要内存是足够的
设多大其实都没关系
当然要比管道要更灵活
接下来的一个进程间通讯机制
就是消息队列
它可以在两个进程之间
传递二进制的块数据
特别需要说明的是
数据块本身 它是有一个类别信息的
接收方可以根据这个消息的类别
然后选择性地处理这些消息
消息队列的创建和获取的函数
叫msgget()
和进程信号量
和我们刚才讲到的共享内存都差不多
函数名字看上去都差不多
使用方式也都差不多
都有key 有个键值 msgget()
很多标志都是共用的
有时候需要命令控制的时候
连命令控制都是共用的
msgsnd()就是将消息
添加到我们消息队列里
把一个消息发送过去
但是发送的时候你要注意
当然会有一个msgid
还有一个msg_ptr
它是指向你要发送的那个消息的
消息数据本身的长度
要通过第三个参数传进去
第四个参数就是发送消息的时候
它的那个发送标志
msg_ptr就是指向那个消息缓冲区的
一个指针
那个消息缓冲区的格式是这个样子
是一个结构体 有两个字段
第一个字段是这个消息的型
也就是消息的类别
第二个字段呢
就是这个消息的缓冲区的长度
它的长度是受限的 512个字节
一般来讲 传一个消息
不会有太长的
只是一个简短的信息传递机制
不能传递太复杂的消息
如果过多 那么消息队列处理的模式
就不如我们的映射内存了
不如我们共享内存了 对吧
就这个意思
消息队列传短消息的
用msgrcv()从消息队列里获取数据
用msgctl()来控制消息队列里面的
某些特定的属性
它的控制方式和原先进程信号量类似
你就拿过来按照这个方式用 就OK了
-1.1 提纲
-1.2 程序设计的基本概念
-1.3 简单C/C++程序介绍
-1.4 程序设计的基本流程
-1.5 基本语法元素
-1.6 程序设计风格
-1.7 编程实践
-第一讲 C/C++基本语法元素--编程实践提交入口
-2.1 提纲
-2.2 结构化程序设计基础
-2.3 布尔数据
-2.4 分支结构
-2.5 break语句
-2.6 循环结构
-2.7 编程实践
-第二讲 程序控制结构--编程实践提交入口
-3.1 提纲
-3.2 函数声明、调用与定义
-3.3 函数调用栈框架
-3.4 编程实践
-第三讲 函数--编程实践提交入口
-4.1 提纲
-4.2 算法概念与特征
-4.3 算法描述
-4.4 算法设计与实现
-4.5 递归算法(一)
-4.6 递归算法(二)
-4.7 容错与计算复杂度
-4.8 编程实践
-第四讲 算法--编程实践提交入口
-5.1 提纲
-5.2 库与接口
-5.3 随机数库(一)
-5.4 随机数库(二)
-5.5 作用域与生存期
-5.6 典型软件开发流程(一)
-5.7 典型软件开发流程(二)
-5.8 编程实践
-第五讲 程序组织与开发方法--编程实践提交入口
-6.1 提纲
-6.2 字符
-6.3 数组(一)
-6.4 数组(二)
-6.5 结构体
-6.6 编程实践
-第六讲 复合数据类型--编程实践提交入口
-7.1 提纲
-7.2 指针基本概念
-7.3 指针与函数
-7.4 指针与复合数据类型(一)
-7.5 指针与复合数据类型(二)
-7.6 字符串
-7.7 动态存储管理(一)
-7.8 动态存储管理(二)
-7.9 引用
-7.10 编程实践
-第七讲 指针与引用--编程实践提交入口
-8.1 提纲
-8.2 数据抽象(一)
-8.3 数据抽象(二)
-8.4 链表(一)
-8.5 链表(二)
-8.6 链表(三)
-8.7 链表(四)
-8.8 函数指针(一)
-8.9 函数指针(二)
-8.10 抽象链表(一)
-8.11 抽象链表(二)
-8.12 编程实践
-第八讲 链表与程序抽象--编程实践提交入口
-9.1 提纲
-9.2 程序抽象与面向对象
-9.3 类类型
-9.4 对象(一)
-9.5 对象(二)
-9.6 类与对象的成员(一)
-9.7 类与对象的成员(二)
-9.8 类与对象的成员(三)
-9.9 继承(一)
-9.10 继承(二)
-9.11 继承(三)
-9.12 多态(一)
-9.13 多态(二)
-9.14 编程实践
-第九讲 类与对象--编程实践提交入口
-10.1 提纲
-10.2 四则运算符重载(一)
-10.3 四则运算符重载(二)
-10.4 关系与下标操作符重载
-10.5 赋值操作符重载(一)
-10.6 赋值操作符重载(二)
-10.7 赋值操作符重载(三)
-10.8 赋值操作符重载(四)
-10.9 赋值操作符重载(五)
-10.10 流操作符重载(一)
-10.11 流操作符重载(二)
-10.12 流操作符重载(三)
-10.13 操作符重载总结
-10.14 编程实践
-第十讲 操作符重载--编程实践提交入口
-11.1 提纲
-11.2 泛型编程概览
-11.3 异常处理机制(一)
-11.4 异常处理机制(二)
-11.5 运行期型式信息(一)
-11.6 运行期型式信息(二)
-11.7 模板与型式参数化
-11.8 题外话:术语翻译
-11.9 泛型编程实践(一)
-11.10 泛型编程实践(二)
-11.11 泛型编程实践(三)
-11.12 泛型编程实践(四)
-11.13 泛型编程实践(五)
-11.14 泛型编程实践(六)
-11.15 泛型编程实践(七)
-11.16 泛型编程实践(八)
-11.17 泛型编程实践(九)
-11.18 泛型编程实践(十)
-11.19 编程实践
-第十一讲 泛型编程--编程实践提交入口
-12.1 提纲
-12.2 程序执行环境(一)
-12.3 程序执行环境(二)
-12.4 程序执行环境(三)
-12.5 程序执行环境(四)
-12.6 输入输出(一)
-12.7 输入输出(二)
-12.8 文件系统
-12.9 设备
-12.10 库(一)
-12.11 库(二)
-12.12 makefile文件(一)
-12.13 makefile文件(二)
-12.14 makefile文件(三)
-12.15 编程实践
-第十二讲 Linux系统编程基础--编程实践提交入口
-13.01 提纲
-13.02 进程基本概念
-13.03 信号
-13.04 进程管理(一)
-13.05 进程管理(二)
-13.06 进程管理(三)
-13.07 进程间通信(一)
-13.08 进程间通信(二)
-13.09 进程间通信(三)
-13.10 进程间通信(四)
-13.11 进程池
-13.12 编程实践
-第十三讲 进程编程--编程实践提交入口
-14.1 提纲
-14.2 线程基本概念
-14.3 线程管理(一)
-14.4 线程管理(二)
-14.5 线程管理(三)
-14.6 线程管理(四)
-14.7 线程同步机制(一)
-14.8 线程同步机制(二)
-14.9 C++11线程库(一)
-14.10 C++11线程库(二)
-14.11 C++11线程库(三)
-14.12 C++11线程库(四)
-14.13 C++11线程库(五)
-14.14 编程实践
-第十四讲 线程编程--编程实践提交入口
-15.1 提纲
-15.2 Internet网络协议
-15.3 套接字(一)
-15.4 套接字(二)
-15.5 编程实践
-第十五讲 网络编程--编程实践提交入口