【Linux 应用编程】进程管理 - 进程间通信IPC之共享内存 mmap
IPC(InterProcess Communication,进程间通信)是进程中的重要概念。Linux 进程之间常用的通信方式有:
- 文件:简单,低效,需要代码控制同步
- 管道:使用简单,默认阻塞
- 匿名管道 pipe:只存在于内核缓冲区,只能用于有血缘关系的进程
- 有名管道 FIFO:在文件系统中存在,可用于无血缘关系的进程
- 信号量:使用复杂,但开销小,操作系统本身支持信号量
- 内存映射区 mmap:进程有无血缘关系都可以
- 本地套接字 socket:稳定可靠
共享内存
通过共享内存,两个不相干的进程可以使用同一段逻辑内存。这块内存通常也是同一段物理内存。每个进程都把这段共享内存连接到自己的地址空间中,直接访问。
共享内存是进程间传递数据的常用方式,非常高效。
共享内存的使用
POSIX 共享内存区的使用包含四个步骤:
- 调用 shm_open 创建一个新的共享内存区对象(或打开一个以存在的共享内存区对象)
- 调用 mmap 把这个共享内存区映射到调用进程的地址空间
- 调用 munmap() 取消共享内存映射
- 调用 shm_unlink()函数删除共享内存段
在编译 POSIX 共享内存应用程序时需要加上 -lrt 参数。
shm_open 函数
shm_open() 函数用来打开或者创建一个共享内存区,两个进程可以通过给 shm_open() 函数传递相同的名字以达到操作同一共享内存的目的。
新建的共享内存区大小默认为 0,需要使用 ftruncate 函数设置大小才能使用。
函数原型:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int shm_open(const char *name, int oflag, mode_t mode);
返回值:
成功返回创建或打开的共享内存描述符(与文件描述符相同作用),失败返回-1。
参数:
- name:创建的共享内存的名称,其它进程可以根据这个名称来打开共享内存
- oflag:以下值的或值:
- O_RDONLY:共享内存以只读方式打开;
- O_RDWR:共享内存以可读写方式打开;
- O_CREAT:共享内存不存在才创建;
- O_EXCL:如果指定了 O_CREAT,但共享内存已经存在时返回错误;
- O_TRUNC:如果共享内存已存在则将大小设置为 0;
- 参数 mode 只有指定 O_CREAT 才有效指出,指出共享内存的权限,与 open()函数
类似。
ftruncate 函数
新建的共享内存默认大小为 0,需要设置共享内存大小。ftruncate()函数可用来调整文件或者共享内存的大小。
函数原型:
#include <unistd.h>
#include <sys/types.h>
int ftruncate(int fd, off_t length);
函数成功返回 0,失败返回-1。
参数:
- fd:需要调整的共享内存或者文件
- length:大小
mmap 函数
共享内存创建或打开后,是不能在进程内直接使用的。需要先映射到当前进程的地址空间。
函数原型:
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
参数:
- addr:指向映射存储区的起始地址,通常将其设置为 NULL,这表示由系统选择该
映射区的起始地址; - len:映射的字节数;
- prot:对映射存储区的保护要求,对指定映射存储区的保护要求不能超过文件 open
模式访问权限。它可以为以下值的或值:- PROT_READ:映射区可读);
- PROT_WRITE:映射区可写;
- PROT_EXEC:映射区可执行;
- PROT_NONE:映射区不可访问。
- flag:映射标志位,可为以下值的或值:
- MAP_FIXED:返回值必须等于 addr。因为这不利于可移植性,所以不鼓励使用此标志;
- MAP_SHARED:多个进程对同一个文件的映射是共享的,一个进程对映射的
内存做了修改,另一个进程也会看到这种变化;
MAP_PRIVATE:多个进程对同一个文件的映射不是共享的,一个进程对映射
的内存做了修改,另一个进程并不会看到这种变化。
- fd:要被映射的文件描述符或者共享内存描述符;
- offset:要映射字节在文件中的起始偏移量。
munmap 函数
函数原型:
#include <sys/mman.h>
int munmap(void *addr, size_t length);
函数成功返回 0,否则返回-1;
参数:
- addr 为 mmap()函数返回的地址
- length 是映射的字节数。取消映射后再对映射地址访问会导致调用进程收到 SIGSEGV 信号。
shm_unlink 函数
函数原型:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int shm_unlink(const char *name);
函数成功返回 0,否则返回-1。
示例
两个没有血缘关系的进程,也可以使用共享内存进行进程间通信:
【Linux 应用编程】进程管理 - 进程间通信IPC之共享内存 mmap的更多相关文章
- 进程间通信IPC之--共享内存
每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲 区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲 ...
- 进程间通信——IPC之共享内存
共享内存是三个IPC机制中的一个.它允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在进行的进程之间传递数据的一种非常有效的方式. 大多数的共享内存的实现,都把由不同进程之间共享 ...
- Linux系统编程@进程管理(一)
课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...
- 【Linux 应用编程】进程管理 - 进程间通信IPC之管道 pipe 和 FIFO
IPC(InterProcess Communication,进程间通信)是进程中的重要概念.Linux 进程之间常用的通信方式有: 文件:简单,低效,需要代码控制同步 管道:使用简单,默认阻塞 匿名 ...
- Linux系统编程@进程管理(二)
1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...
- Linux系统编程@进程通信(一)
进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...
- UNIX环境高级编程——进程管理和通信(总结)
进程管理与通信 进程的管理 进程和程序的区别: 进程: 程序的一次执行过程 动态过程,进程的状态属性会发生变化 程序:存放在磁盘上的指令.数据的有序集合 是个文件,可直观看到 程序program ...
- Linux学习之进程管理(十九)
Linux学习之进程管理 进程查看 查看系统中所有进程,使用BSD操作系统的格式 语法:ps aux 选项: a:显示所有前台进程 x:显示所有后台进程 u:显示这个进程是由哪个用户产生的 语法:ps ...
- 【Linux学习】Linux系统管理1—进程管理
Linux系统管理1-进程管理 一.Linux的三种进程 Linux包括3中不同类型的进程: 交互进程:由一个shell启动的进程.交互进程可以在前后台运行 批处理进程:该进程和终端无联系,是一个进程 ...
随机推荐
- Qualcomm_Mobile_OpenCL.pdf 翻译-8-kernel性能优化
这章将会说明一些kernel优化的小技巧. 8.1 kernel合并或者拆分 一个复杂的应用程序可能包含很多步骤.对于OpenCL的移植性和优化,可能会问需要开发有多少个kernel.这个问题很难回答 ...
- Java Script语法
JavaScript 语法 JavaScript 是一个程序语言.语法规则定义了语言结构. JavaScript 语法 JavaScript 是一个脚本语言. 它是一个轻量级,但功能强大的编程语言. ...
- JavaScript调试技巧之断点调试
首先,在各个浏览器中,断点调试支持的最好的当然是Firefox,Firefox不仅可以使用Firebug调试页面js脚本,还可以用高级调试工具例如JavaScript Debugger (Venkma ...
- MySQL 表的增删查改
一.插入数据 1. INSERT ... VALUES ... INSERT INTO <表名> [ <列名1> [ , … <列名n>] ] VALUES (值1 ...
- Codeforces Round #606 Div. 2 比赛总结
比赛情况 bq. A题 Wrong Answer on test 2 , E题sb题没切.bqbqbq. 比赛总结 bq. 那就直接上题解吧!^-^ A 数位dp,分类讨论,注意细节. Talk is ...
- java map 根据 map的value值进行排序
//根据销量排行查询 public void queryGoodsByHotCount(){ //将map集合键和值封装到entry对象中 然后转换成set集合 Set<Entry<Int ...
- 【30分钟学完】canvas动画|游戏基础(7):动量守恒与多物体碰撞
前言 一路沿着本系列教程学习的朋友可能会发现,前面教程中都尽量避免提及质量的概念,很多运动概念也时刻提醒大家这不是真实的物体运动.因为真实的物体运动其实跟质量都是密不可分的,而且质量的引入自然必须提及 ...
- ip addr详解
Windows上查看IP地址是ipconfig, Linux上是ifconfig,但是Linux上还有一个命令叫ip addr可以查看IP地址. ip addr : lo: <LOOPBACK, ...
- 【NOIP2016提高A组模拟9.15】Map
题目 分析 发现,当原图是一棵树的时候,那么新建一条边后,就会变成环套树, 而环内的所有点对都是安全点对,如果环中有k个点,答案就是\(k(k-1)\) 联想到,当把原图做一遍tarjan缩点,每个环 ...
- c++ copy和operator =
目录(?)[+] 构造函数 拷贝构造函数 赋值函数 C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法.下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函 ...