Linux——进程通信之共享内存

目录

一.  回顾上文

二.共享内存

1.定义

2.特点:

3.实现步骤:

如下为成功链接共享内存使用权的完整步骤:

4.函数介绍

        4.1shmget函数

        4.1.2参数介绍       

        4.2ftok函数:

        4.2.1参数介绍

                关于ftok(); shmget();函数的代码实验:

        代码运行: 

                举个生活中的例子:

                运行结果:

                所以有两种方法解决: 

               4.3shmctl();——用于删除共享内存空间

               参数介绍:

               返回值:

              代码演示: 

    接下来就是第三步:关联各进程和共享内存空间的之间的“羁绊”!

            4.4shmat();——获取共享内存空间的地址

         参数介绍:

        代码演示: 

        运行结果:

         4.6 shmdt();——取消与共享内存空间的关联

         代码演示:

        最后就是双方的数据通信了!

 二.最终代码图:

        Comm.hpp:

        Sever.cc:

        Client.cc: 

        运行结果:

三.总结:

共享内存相比较于管道而言,两个进程在进行进程间通信时,需要经历几次数据的拷贝呢?

共享内存的缺点:


一.  回顾上文

        我所说的进程间数据通信指的是:以两个进程为例,一个进程只写,另一个进程只读的方式进行数据通信,它们的实现是单向的。

        1.而管道就是进程通信的一种方式,它是一种半双工通信方式,即数据是单向的(一个进程读,另一个进程写)。

        2.管道分为匿名管道和命名管道。

        3.匿名管道是用来让具有血缘关系的父子进程进行专门的数据通信,使用的是pipe函数创建管道,进而使用fork函数创建出子进程,便可开始数据通信。但是匿名管道需要关闭相应的文件描述符,父进程要么只读,要么只写,子进程也是一样。

        4.命名管道是在内存中对应一个缓冲区,读进程从管道读数据是一次性操作,数据一旦被读走,它就会被丢弃,释放空间以便于让写进程能够写更多的数据。而命名管道可以让没有任意的两个进程也可以进行数据通信,使用的方式是mkfifo函数创建管道文件,之后便是以文件的形式进行IO传输。

        

        除了管道之外,便是要学习另外一种数据通信的方式:System V。而System V通信中最主要常考的就是共享内存了,所以我们接下来讲述的重点是共享内存。

         上图中,这两个进程都是独立的,在系统底层它们都有各自的内核数据结构(struct_task)——简称PCB,也有各自的进程地址空间(mm_struct),虽然它们的代码数据都在内存中,但互不影响干扰,所以是独立的。

        而想让两个毫不相干的进程采取通信,就必须要让两个进程看到同一份公共的资源,而今天的这份公共资源就是——共享内存。

二.共享内存

1.定义

        共享内存是存放在物理内存中的一段空间,该空间由操作系统分配与管理。与文件系统类似的是,操作系统在管理共享内存时,不仅仅有内存数据快,同时还会创建相结构体来记录该共享内存属性,以便于管理。

        因此共享内存并不只有一份,我们可以根据需求申请多个共享内存。

2.特点:

        相较于管道而言,共享内存不仅能够用于非父子进程之间的通信,而且访问数据的速度也比管道要快。这得益于通信直接访问内存,而管道则需要先通过操作系统访问文件再获得内存数据。

3.实现步骤:

        有了共享内存,就可以让两个进程指向这块共享空间资源了。于是进行第二步,让各个进程拥有这份公共资源的使用权限,它们才可以进行数据通信。

        但是想拥有共享内存的使用权并不简单,需要执行多个步骤才能实现。

如下为成功链接共享内存使用权的完整步骤:

4.函数介绍

         4.1shmget函数

        shmget函数创建共享存储空间并返回一个共享存储标识符,成功完成后,shmget () 应返回一个非负整数,即共享内存标识符:否则,它应返回-1 并设置 Errno以指示错误。

        4.1.2参数介绍
       

        如上shmget函数参数: 三个参数,第二个是设置共享内存空间的大小,第三个参数是标志位,类似于open函数的O_RDONLYO 、O_CTREAT等宏定义选项。

        下图为第三参数的默认选项,有两个:IPC_CREAT、IPC_EXCL

 

IPC_CREAT:若没有,则创建共享内存空间;若该该共享内存空间存在,则会获取。

IPC_EXCL:   不能单独使用,必须搭配IPC_CREAT。

合起来的作用就是: 如果空间不存在,就创建;若存在该空间,就返回错误error

        而第一个参数key_t key,该参数是ftok函数的返回值,所以想要使用key,就得先获取ftok函数的返回值。

        4.2ftok函数:

         4.2.1参数介绍

        ftok函数有两个参数,第一个参数与open函数的第一参数一样,都需要指定路径的文件名;第二参数id,它的取值范围是0-255之间的数值,在这个范围内随意取即可。

        使用ftok函数成功后,返回一个key_t类型的键值,若函数使用失败出错,返回-1 。

关于ftok(); shmget();函数的代码实验:

        注:在该实验中,用两个.cc文件模拟了两个进程,使用一个头文件去封装了ftok、shmget函数:

代码运行: 

        通过结果发现,两个进程的key地址都相等,这是因为这两个进程在调用getKey()时,ftok函数的参数是一样的,所以它们被分配的是同一个key值。

        既然两个进程拥有相同的Key值,这就为它们能够看到同一份共享内存空间打下了坚实的基础,之后便是创造共享内存空间了,在这里我采用的是Sever进程去创建它,这个没有限制,哪个进程去创建它都可以。但是既然有一个进程创建了,另一个进程直接获取该共享空间即可,没必要再去创建一个,前人栽树(Sever进程),后人乘凉即可(Client进程)。 

举个生活中的例子:<

评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙予清的zzz~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值