Linux-进程间通信(三): 共享内存
1. 共享内存:
共享内存方式可以在多个进程直接共享数据,因为其直接使用内存,不要多余的拷贝,是速度最快的IPC方式;
共享内存有两种实现方式,使用mmap和shm方式,如下图:
(1) mmap方式是将文件与进程地址空间进行映射,对实际物理内存影响小;
(2) shm方式是将每个进程的共享内存与实际物理存储器进行映射,对实际物理内存影响大;
由于XSI IPC自身缺点,所以建议使用mmap来实现共享内存;
2. mmap相关函数原型:
#include <sys/mman.h>void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off);ret = 成功返回映射区域开始地址,失败返回MAP_FAILED
addr-参数用来指定映射区域的起始地址。通常设置为0,表示有系统选择映射区域的起始位置;
filedes-要映射文件的描述符。在映射文件到地址空间之前,先要打开文件;
len-映射的字节数;
off-要映射字节在文件中的起始偏移量;
prot-对映射存储区的保护要求,指定为PROT_NONE(不可访问), PROT_READ(可读), PROT_WRITE(可写), PROT_EXEC(可执行)的任意组合或者按位或;
但是对于映射存储区的保护要求不能超过文件open的权限,比如文件是只读打开的,则不能指定PROT_WRITE;
flag-MAP_FIXED 返回值必须等于addr,如果未制定此标志,addr非0,则作为一种建议,内核不保证会使用该地址。为了获得最大的可移植性,建议addr指定为0;
MAP_SHARED 说明了本进程对映射区域进行储存操作的配置。此标志指定存储操作修改映射文件,也就是相当于对该文件执行write;
MAP_PRIVATE 本标志说明对映射区存储操作会创建该映射的一个副本。所以后续操作都会引用该副本,而不是原始文件;
MAP_SAHRED 和 MAP_PRIVATE 必须指定其一,但是不能同时指定;
修改现有映射区的权限,与上面mmap中的prot字段相同;
#include <sys/mman.h>int mprotect(void *addr, size_t len, int prot);ret = 成功返回0,失败返回-1
如果共享内存中的页已被修改,则可以调用msync将该页冲洗到映射的文件中;
如果映射是私有的,那么不修改映射文件;
#include <sys/mman.h>int msync(void *addr, size_t len, int flags);ret = 成功返回0 失败返回-1
flags- MS_ASYNC和MS_SYNC必选其一;
MS_ASYNC-异步sync,无需等待,系统调度;
MS_SYNC-同步sync,需要等到操作完成;
MS_INVALIDATE-可选标志,通知操作系统丢弃没有同步的页;--一般不使用;
进程终止,或者调用munmap,内存映射就被自动解除,关闭文件描述符filedes并不会解除映射;
调用munmap不会是映射内存内容写到磁盘文件,share类型写磁盘是内核根据算法自动执行,private则丢弃修改;
#include <sys/mman.h>int munmap(caddr_t addr, size_t len);ret-成功返回0 失败返回-1
3. 文件映射到进程位置:
文件映射到进程地址空间中堆和栈直接的一段内存。
4. 子进程影响:
fork之后,因为子进程复制父进程的地址空间,而存储映射是该地址空间的一部分,所以子进程继承了该存储映射区域,但是当调用了exec函数组之后的新程序则不继承该映射区;
测试代码:--测试两个进程通过mmap映射信息,测试共享时,数据情况,和共享后数据情况;
common.h
1 #include <sys/mman.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <fcntl.h> 5 #include <string.h> 6 7 #define MMAP_FILE "/var/tmp/test_mmap" 8 #define NAME_LEN 64 9 10 typedef struct book { 11 int id; 12 char name[NAME_LEN]; 13 }book_t;
mmap_proc1.c -- 进程1,做映射,映射超过文件长度的区域
1 #include "common.h" 2 3 int main(int argc, char *argv[]) 4 { 5 int fd = -1; 6 int i = 0; 7 book_t *book = NULL; 8 9 if ((fd = open(MMAP_FILE, O_RDWR | O_CREAT | O_TRUNC)) < 0){ 10 perror("open file error\n"); 11 return -1; 12 } 13 14 if (lseek(fd, sizeof(book_t) * 2 - 1, SEEK_SET) < 0){ 15 perror("lseek error\n"); 16 close(fd); 17 return -1; 18 } 19 20 write(fd, "", 1); 21 22 if ((book = (book_t *)mmap(NULL, sizeof(book_t) * 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED){ 23 perror("mmap error\n"); 24 return -1; 25 } 26 27 close(fd); 28 29 for (i = 0; i < 4; i++){ 30 char name[16] = { 0 }; 31 snprintf (name, 15, "book-%d", i); 32 33 (*(book + i)).id = i; 34 strncpy((*(book + i)).name, name, NAME_LEN - 1); 35 } 36 37 sleep(10); 38 39 munmap(book, sizeof(book_t) * 4); 40 41 return 0; 42 }
mmap_proc2.c -- 进程2,做映射,映射与进程1相同区域
1 #include "common.h" 2 3 int main(int argc, char *argv[]) 4 { 5 int fd = -1; 6 int i = 0; 7 book_t *book = NULL; 8 9 if ((fd = open(MMAP_FILE, O_RDWR | O_CREAT)) < 0){ 10 perror("open file error\n"); 11 return -1; 12 } 13 14 if ((book = (book_t *)mmap(NULL, sizeof(book_t) * 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED){ 15 perror("mmap error\n"); 16 return -1; 17 } 18 19 close(fd); 20 21 for (i = 0; i < 4; i++){ 22 printf("id:%d, name:%s\n", (*(book+i)).id, (*(book+i)).name); 23 } 24 25 munmap(book, sizeof(book_t) * 4); 26 27 return 0; 28 }
转载于:https://www.cnblogs.com/wanpengcoder/p/5299148.html
Linux-进程间通信(三): 共享内存相关推荐
- [转]Linux 进程间通信:共享内存
(上) 级别: 初级 郑彦兴 (mlinux@163.com), 国防科大攻读博士学位 2003 年 5 月 01 日 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B ...
- Linux进程间通信——使用共享内存
下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...
- Linux——进程间通信(共享内存shm)笔记
文章目录 前言 一.共享内存的通信原理 二.共享内存函数 1.共享内存实现步骤 2.函数的说明 1.shmget( )函数 2.shmat( )函数 3.shmdt( )函数 三.代码示例: 执行结果 ...
- Linux进程间通信:共享内存mmap、xsi和posix
前言 本文主要说明在Linux环境上如何使用共享内存.阅读本文可以帮你解决以下问题: 什么是共享内存和为什么要有共享内存? 如何使用mmap进行共享内存? 如何使用XSI共享内存? 如何使用POSIX ...
- Linux——进程间通信(共享内存【mmap实现+系统V】)
共享内存 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式,两个不同的进程A.B共享内存的意思就是:同一块物理内存被映射到进程A.B各自的进程地址空间,进程A可以同时看到进程B对共享内存中 ...
- Linux进程间通信(四) - 共享内存
共享内存的优势 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只 ...
- Linux进程间通信:共享内存与管道
references: [1] IPC through shared memory [2] Inter Process Communication (IPC) [3] https://www.geek ...
- Linux进程间通信(七)---共享内存之shmget()、shmat()、shmdt()及其基础实验
/********************************************************************* * 2019年6月26日声明:本博客资源下载积分最开始为免 ...
- Linux进程间通信:共享内存(shm)
目录 ★ key值说明 ★ shmget函数 ★ shmat函数 ★ shmdt函数 ★ shmctl函数 ★ 操作说明 ★ IPC相关指令 简介:共享内存指 (shared memory)在多处理器 ...
- Linux进程间通信:共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
共享内存函数由shmget.shmat.shmdt.shmctl四个函数组成.下面的表格列出了这四个函数的函数原型及其具体说明. 1. shmget函数原型 shmget(得到一个共享内存标识符或 ...
最新文章
- datetime 索引_date类型和varchar类型在查询索引效率上比较
- NYOJ-199 无线网络覆盖
- wps右键新建里面没有word和excel_WPS竟然出过这么多实用工具?每个都免费无广告,简直相见恨晚...
- 剑指Offer_14_链表中倒数第k个结点
- WEB打印大全(转)
- (网络编程)UDP实现聊天
- chrome js 读取文件夹_使用JavaScript遍历本地文件夹的文件
- PHP 字符串替换 substr_replace 与 str_replace 函数
- 阿里云首次公布年度3大战略方向,中台做厚,做强生态,还要再招5000人
- 1-5分层API(Layered APIs)
- 村庄规划用途管制的相关内容
- 华为Mate 20 X 5G版本月起全球开卖:国内上市的首款5G手机
- 免费拿走我的代码可以,但请对使用我的时间付费
- Oracle 数据库逻辑结构.md
- CentOS7下Telegraf+InfluxDB+Grafana 搭建服务器监控平台
- 干货 | 集成学习综述与代码实现
- HL-USB TO RS232驱动
- 黑苹果 无线网卡相关配置
- VC中用内存映射文件处理大文件
- 如何制作扫描连接WIFI二维码,手机扫码即可一键连接无线WIFI网络
热门文章
- spring boot 教程(二)模板依赖
- python re 简单实例_python的re正则表达式实例代码
- 照片浏览器_2020护考报名失败!只因照片太大瞎忙乎三小时...
- python开发板卡驱动开发_一款能让你发挥无限创意的MicroPython开发板—TPYBoard开发板测...
- 系统学习深度学习(二十四)--WRN
- const 修饰的对象属性可以修改,但是修饰的常量就不可以修改
- matlab拼接tiff文件_ImageJ实用技巧——自动图片拼接(基本功能篇)
- c语言计算总分和平均分float,用C语言编程平均分数
- 偏微分方程数值解法python_Python数值计算----------求解简单的偏微分方程
- ssl证书 所属项目怎么上传_Typora + 七牛云图床快速配置,告别手动上传图片!...