linux网络编程之system v共享内存
接着上次的共享内存继续学习,这次主要是学习system v共享内存的使用,下面继续:
跟消息队列一样,共享内存也是有自己的数据结构的,system v共享内存也是随内核持续的,也就是说当最后一个访问内存共享的进程结束了,内核也不会自动删除共享内存段,除非显示去删除共享内在,其数据结构跟消息队列很类似:
跟消息队列一样,共享内存也提供了四个函数:
下面详细来看一下各函数的用法:
用法跟msgget函数一模一样,下面用代码来实验一下:
编译运行一下:
当共享内存创建好之后,则希望往共享内存当中进行写入操作,在写入之前,需要将共享内存映射到进程的地址空间,接下来来看一下第二个函数:
下面对其参数进行说明:
这个也是推荐的作法
关于这点,其实可以从帮助文档中查看到:
其中“SHMLBA”是等于4K=4096b的值,比如说shmaddr地址指定为4097,而这时所连接地址并不是4097,而是4097-(4097%4096)=4097-1=4096,而如果shmaddr地址指定为8193,这时所连接的地址为:8193-(8193%4096)=8193-1=8192,就是这个意思。
通常情况下,shmflg都指定为0,表示连接到的共享内存既可读也可以写。
下面来看另外一个函数:
所以接下来将共享内存映射到进程的地址空间当中,具体写法如下:
当执行完之后,可以解决映射:
下面运行一下:
为了观看到连接数,可以sleep一段时间,修改程序如下:
接下来从共享内存中读取数据:
运行:
之前已经说过,共享内存是随内核持续存在的,也就是它不会自动从内核中删除,可以通过下面这个函数来手动删除它,如下:
其中cmd的值可取如下:
下面则用此函数来删除共享内存段,当进程结束之后:
编译运行:
当然这样使用有点粗暴,还没等别人从共享内存中读走数据就被删除了,下面来让程序更加合理一点从内核删除,当有人读取了共享内存的数据时,会将quit字串写到共享内存的前面四个字节当中,所以在写程序中可以循环来做一个监听,如下:
接下来,修改读取程序:
下面来运行一下:
这时查看一下共享内存是否还存在于内核当中:
另外要注意的一点是:共享内存的前面四个字节的数据类型不一定,可以为整型,也可以为字符串,如下:
目前前四个字节为整型,也可以将数据写入到姓名字段中,将结构体修改一下:
运行效果其实也是一样的,为什么呢,因为我们比较的仅仅只是内存:
只要保证有四个字节的空间,就能够存放四个字符,不在乎是什么数据类型。