进程间通信之共享内存

发布于:2024-09-18 ⋅ 阅读:(135) ⋅ 点赞:(0)

磁盘映射

概述

存储映射 I/O (Memory-mapped I/O) 使一个磁盘文件与存储空间中的一个缓冲区相
映射。
于是当从缓冲区中取数据,就相当于读文件中的相应字节。
于此类似,将数据存入缓冲区,则相应的字节就自动写入文件。
这样,就可在不使用 read write 函数的情况下,使用地址(指针)完成 I/O
作。
使用存储映射这种方法,首先应通知内核,将一个指定文件映射到存储区域中。这个映
射工作可以通过 mmap 函数来实现。

优点

 相对于文件的读写,速度较快

相关函数

mmap

作用:建立映射
语法

#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags,int fd,
off_t offset);
参数 :
addr: 生成的映射的地址 , NULL, 让系统自动寻找合适的地址
length: 开启的内存大小
prot: 权限
PROT_READ 可读
PROT_WRITE 可写
flags 标志位
MAP_SHARED 共享的 -- 对映射区的修改会影响源文件
MAP_PRIVATE 私有的
fd: 映射的文件的文件描述符
offset: 偏移量 , 一般写 0
返回值 :
开启的映射的首地址

 munmap

作用:释放映射的缓冲区
语法:
#include <sys/mman.h>
int munmap(void *addr, size_t length);
参数 :
addr: 要释放的映射的地址
length: 释放的长度
注意 : 该函数只是断开了该进程与映射区之间的连接

truncate

作用:扩展映射的缓存区大小
语法

int truncate(const char *path, off_t length);

参数 :
path: 文件地址
length: 长度
注意 :
如果文件大小大于 length, 此时删除多余部分
如果文件大小小于 length, 此时扩展

使用步骤

1.打开文件获取文件描述符

2.扩展映射的缓冲区大小

3.建立映射

4.读或写

5.断开映射 

共享内存

概述

共享内存允许两个或者多个进程共享给定的存储区域。
物理内存 : 电脑物理内存就是指的内存条
虚拟内存 : 是系统默认在 C 盘划分的一部分磁盘空间临时存储数据用的

特点

1 、共享内存是进程间共享数据的一种最快的方法。 一个进程向共享的内存区域写入了
数据,共享这个内存区域的所有进程就可以立刻看到其中的内容 .
2 、使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥。 若一个进程
正在向共享内存区写数据,则在它做完这一步操作前,别的进程不应当去读、写这些数

共享内存限制值如下

1、共享存储区的最小字节数:1

2 、共享存储区的最大字节数: 32M
3 、共享存储区的最大个数: 4096
4 、每个进程最多能映射的共享存储区的个数: 4096

相关命令

ipcs -m

ipcrm -m 要删除的共享内存 id

相关函数

shmget

作用:获取共享内存的id
语法

所需头文件

#include <sys/ipc.h>
#include <sys/shm.h>
函数
int shmget(key_t key, size_t size, int shmflg);
参数
key:IPC 键值 ( 进程间通讯键值 )
size: 该共享存储段的长度 ( 字节 )
shmflg: 标识函数的行为及共享内存的权限。
IPC_CREAT: 创建 , 如果不存在就创建
IPC_EXCL: 如果已经存在则返回失败
位或权限位 : 共享内存位或权限位后可以设置共享内存的访问权限,格式和
open 函数的 mode_t 一样 , 但可执行权限未使用。
返回值 :
成功:返回共享内存标识符。
失败:返回 -1

shmat

作用:建立映射
语法

#include <sys/types.h>

#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr,int shmflg);
参数 :
shmid :共享内存标识符。
shmaddr :共享内存映射地址 ( 若为 NULL 则由系 统自动指定 ) ,推荐使用
NULL
shmflg :共享内存段的访问权限和映射条件
0: 共享内存具有可读可写权限。
SHM_RDONLY :只读。
SHM_RND :( shmaddr 非空时才有效)没有指定 SHM_RND 则此段连接到
shmaddr 所指定的地址上 (shmaddr 必需页对齐 )
指定了 SHM_RND 则此段连接到 shmaddr- shmaddr%SHMLBA 所表示的地址
上。
返回值:
成功:返回共享内存段映射地址
失败:返回 -1
注意 :
shmat 函数使用的时候第二个和第三个参数一般设为 NULL 0, 即系统自动指定共享
内存地址 , 并且共享内存可读可写

shmdt

作用:断开映射
语法

所需头文件

#include <sys/types.h>
#include <sys/shm.h>
函数
int shmdt(const void *shmaddr);
参数:
shmaddr: 共享内存映射地址。
返回值:
成功返回 0
失败返回 -1

 shmctl

作用:共享内存空间的控制
语法
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
shmid :共享内存标识符。
cmd :函数功能的控制。
IPC_RMID :删除。
IPC_SET :设置 shmid_ds 参数。
IPC_STAT :保存 shmid_ds 参数。
SHM_LOCK :锁定共享内存段 ( 超级用户 )
SHM_UNLOCK :解锁共享内存段。
buf :指向 struct shmid_ds 结构的指针,用于存储共享内存段的信息。可以为
NULL ,表示不获取共享内存段的信息。
返回值:
成功返回 0
失败返回 -1
注意:
SHM_LOCK 用于锁定内存,禁止内存交换。并不代表共享内存被锁定后禁止其它进
程访问。其真正的意义是:被锁定的内存不允许被交换到虚拟内存中。这样做的优势在
于让共享内存一直处于内存中,从而提高程序性能

使用步骤

1.获取key

2.获取共享内存的id

3.建立映射

4.读或写

5.断开映射 

代码示例 

#include<stdio.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <sys/types.h>

#define BUFSIZE 1024

int main(int argc, char const *argv[])

{

    // 1,获取key

    // key_t ftok(const char *pathname, int proj_id);

    int key=ftok("/",9527);

    // 2,获取共享内存的id

    //  int shmget(key_t key, size_t size, int shmflg);

    int shmid=shmget(key,BUFSIZE,IPC_CREAT|0666);

    // 3,建立映射

    // void *shmat(int shmid, const void *shmaddr, int shmflg);

    char* buf=(char*)shmat(shmid,NULL,0);

    // 4,读或写----写

    buf[0]=98;

    buf[1]=66;

    // 5,断开映射

    // int shmdt(const void *shmaddr);

    shmdt(buf);

    return 0;

}

进程间通信总结

1,文件

2, 信号
缺点 : 传输数据量小
优点 : 方便
3, 管道 :
优点 : 携带数据
缺点 : 没有格式 , 先入先出 , 只能读一次 , 麻烦
分类 :
无名管道
有名管道
4, 消息队列
优点 : 有类型 , 有格式
5, 共享内存
优点 :

网站公告

今日签到

点亮在社区的每一天
去签到