进程间通信--system V共享内存
Posted 你快看看我
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程间通信--system V共享内存相关的知识,希望对你有一定的参考价值。
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据
(1)申请共享资源
(2)进程1 和进程2分别挂接对应的共享内存到自己的地址空间(共享区)
(3)双方就看到了同一份资源,即可以进行正常通信了
一.共享内存函数
1.shmget函数
功能:用来创建共享内存
原型:int shmget(key_t key, size_t size, int shmflg);
参数:
(1) key:这个共享内存段名字
如何保证多个进程看到同一个共享内存呢?通过key来进行唯一性的区分。那么我们如何保证AB进程获得的是同一个key值呢?通过函数key_t ftok(const char *pathname,int proj id);
其中参数可以按照自己的情况任意填写,但AB进程填写的是一样的,这样就可以保证AB两个进程使用的同一个规则形成的key
(2)size:共享内存大小
(3)shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的。若只设置IPC_CREAT,如果没有共享内存,创建之,有共享内存就获取之;若IPC_CREAT和IPC_EXCL同时设置,如果目标共享内存不存在就创建,如果已经存在则出错返回
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1
2.shmat函数
功能:将共享内存段连接到进程地址空间
原型:void *shmat(int shmid, const void *shmaddr, int shmflg);
参数:
(1) shmid: 共享内存标识
(2)shmaddr:指定连接的地址
(3)shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1
注:
(1)shmaddr为NULL,核心自动选择一个地址
(2)shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
(3)shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)
(4)shmflg=SHM_RDONLY,表示连接操作用来只读共享内存
3.shmadt函数
功能:将共享内存段与当前进程脱离
原型:int shmdt(const void *shmaddr);
参数:
(1)shmaddr: 由shmat所返回的指针
(2)返回值:成功返回0;失败返回-1
注:将共享内存段与当前进程脱离不等于删除共享内存段,所有的ipc资源都是随内核的,不随进程,若清楚,则OS重启或者进程退出时用调用释放,相关指令也可删除
4.shmctl函数
功能:用于控制共享内存
原型:int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
(1)shmid:由shmget返回的共享内存标识码
(2)cmd:将要采取的动作(有三个可取值)
(3)buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1
二.shmid 和 key区别以及注释
key:是一个用户层生成的唯一键值,核心作用是为了区分“唯一性”,不能用来进行IPC资源的操作,类比文件的inode号
shmid:是一个系统给我们返回的IPC资源标识符,用来操作IPC资源,类比文件的fd
(1)共享内存的生命周期随OS
(2)共享内存不提供任何同步互斥的操作,双方彼此独立
(3)共享内存是所有的进程间通信中,速度最快的
(4)共享内存大小,系统在分配shm的时候,是按照4kb为基本单位,比如如果申请4097kb,系统会给你4096kb+4096kb,会产生浪费
三.system V信号量
信号量:本质是一个计数器用来描述临界资源中资源数目的计数器
多个进程不能操作同一个count值,因为信号量不等于count。信号量是保护临界资源的安全性,每个进程都得先申请信号量,前提是每个人都得先看到信号量信号量本身就是一个临界资源,需要保护其他临界资源,先得保证自己的安全,通过PV操作,并且PV操作是原子的。
1.让进程看到同一份资源(内存空间),这个资源称为临界资源
2.进程内的所有代码不是全部的代码都在访问临界资源,而是只有一部分在访问,可能造成数据不一致的问题是,这部分少量的代码,访问临界资源的代码叫做临界区
3.为了避免数据不一致,保护临界资源需要对临界区代码进行某种保护(互斥)
4.互斥:一部分空间任何时候有,且只能有一个进程在进行访问,串行化的执行
5.加锁和解锁是有对应代码的,本质是对临界区进行加锁和解锁的完成互斥操作
以上是关于进程间通信--system V共享内存的主要内容,如果未能解决你的问题,请参考以下文章
Linux篇第十一篇——进程间通信(管道+system V共享内存)
Linux篇第十一篇——进程间通信(管道+system V共享内存)