接着上次的共享内存继续学习,这次主要是学习system v共享内存的使用,下面继续:

linux网络编程之system v共享内存_数据

跟消息队列一样,共享内存也是有自己的数据结构的,system v共享内存也是随内核持续的,也就是说当最后一个访问内存共享的进程结束了,内核也不会自动删除共享内存段,除非显示去删除共享内在,其数据结构跟消息队列很类似:

linux网络编程之system v共享内存_数据_02

linux网络编程之system v共享内存_共享内存_03

 跟消息队列一样,共享内存也提供了四个函数:

linux网络编程之system v共享内存_共享内存_04

下面详细来看一下各函数的用法:

linux网络编程之system v共享内存_共享内存_05

用法跟msgget函数一模一样,下面用代码来实验一下:

linux网络编程之system v共享内存_消息队列_06

编译运行一下:

linux网络编程之system v共享内存_共享内存_07

linux网络编程之system v共享内存_数据_08

当共享内存创建好之后,则希望往共享内存当中进行写入操作,在写入之前,需要将共享内存映射到进程的地址空间,接下来来看一下第二个函数:

linux网络编程之system v共享内存_数据_09

下面对其参数进行说明:

linux网络编程之system v共享内存_数据_10

这个也是推荐的作法

linux网络编程之system v共享内存_数据_11

linux网络编程之system v共享内存_数据_12

关于这点,其实可以从帮助文档中查看到:

linux网络编程之system v共享内存_数据_13

其中“SHMLBA”是等于4K=4096b的值,比如说shmaddr地址指定为4097,而这时所连接地址并不是4097,而是4097-(4097%4096)=4097-1=4096,而如果shmaddr地址指定为8193,这时所连接的地址为:8193-(8193%4096)=8193-1=8192,就是这个意思。

linux网络编程之system v共享内存_数据_14

通常情况下,shmflg都指定为0,表示连接到的共享内存既可读也可以写。

下面来看另外一个函数:

linux网络编程之system v共享内存_共享内存_15

所以接下来将共享内存映射到进程的地址空间当中,具体写法如下:

linux网络编程之system v共享内存_共享内存_16

当执行完之后,可以解决映射:

linux网络编程之system v共享内存_数据_17

下面运行一下:

linux网络编程之system v共享内存_数据_18

为了观看到连接数,可以sleep一段时间,修改程序如下:

linux网络编程之system v共享内存_消息队列_19

linux网络编程之system v共享内存_共享内存_20

接下来从共享内存中读取数据:

linux网络编程之system v共享内存_数据_21

运行:

linux网络编程之system v共享内存_消息队列_22

之前已经说过,共享内存是随内核持续存在的,也就是它不会自动从内核中删除,可以通过下面这个函数来手动删除它,如下:

linux网络编程之system v共享内存_共享内存_23

其中cmd的值可取如下:

linux网络编程之system v共享内存_消息队列_24

下面则用此函数来删除共享内存段,当进程结束之后:

linux网络编程之system v共享内存_消息队列_25

编译运行:

linux网络编程之system v共享内存_数据_26

当然这样使用有点粗暴,还没等别人从共享内存中读走数据就被删除了,下面来让程序更加合理一点从内核删除,当有人读取了共享内存的数据时,会将quit字串写到共享内存的前面四个字节当中,所以在写程序中可以循环来做一个监听,如下:

linux网络编程之system v共享内存_共享内存_27

接下来,修改读取程序:

linux网络编程之system v共享内存_消息队列_28

下面来运行一下:

linux网络编程之system v共享内存_消息队列_29

这时查看一下共享内存是否还存在于内核当中:

linux网络编程之system v共享内存_数据_30

另外要注意的一点是:共享内存的前面四个字节的数据类型不一定,可以为整型,也可以为字符串,如下:

linux网络编程之system v共享内存_消息队列_31

目前前四个字节为整型,也可以将数据写入到姓名字段中,将结构体修改一下:

linux网络编程之system v共享内存_数据_32

linux网络编程之system v共享内存_数据_33

运行效果其实也是一样的,为什么呢,因为我们比较的仅仅只是内存:

linux网络编程之system v共享内存_消息队列_34

只要保证有四个字节的空间,就能够存放四个字符,不在乎是什么数据类型。