共享内存概念
共享内存其实就像malloc一样,在内促上开辟一块空间,如果是需要多次复用的内容,我们就可以用共享内存来节省空间,通过映射的方式把共享内存的内容映射到自己的内存中。

但是它的特性会导致我们读的读写的写,各干各的,所以我们需要加上一个命名管道来限制它,当我们达成某些条件时往命名管道里写内容当信号,而收到的那一方就知道,OK我们写的到一段落可以开始读了。
共享内存实现
先看我们的静态变量和宏以及我们类的成员。


开始构造基本结构
正是因为我们不想各做各的,所以我们加上命名管道进行约束,那么这样我们就得对管理者和使用者进行区分了,如果是管理者构造,那么代表共享内存还未开辟,那我们就要先开辟,而如果是使用者则代表已经存在,那我们只需要找到对应的即可。

当然关于命名管道的找,也是值得一提的,首先管理者创建一个命名管道,然后ftok创建的id就会被设置到管道里,毕竟叫命名管道,当然得有个名,这个名就由管理者来定,此时我使用者会拿着同样的id来找管道,OK 这样双方就能找到并建立联系,这样命名管道就成功了。

当然肯定有疑问,凭啥我使用者能拿到一样的id啊



当然是之前提过的权限问题啦,我们create的和get仅仅只差一个IPC_EXCL,
这个参数单独用没有用,而和creat一结合,就代表必须是不存在的id,所以creat能稳定保证自己是完全全新的,而我get只有creat找,找不到才创建,那这不妥妥就找到creat身上去了吗。
最后上面成功走完后,代表创建好了也能找到,那么链接一下稳定关系就好了。

那么如果我们想想看信息,可以使用shmctl来查看。

我们也可以用其他我们专门设置的外部接口提供共享内存的其他信息

最后我们进行析构删除它,不过需要注意的是共享内存可以通过ipcs -m 查看,然后再用ipcrm -m删除它,但是我们还有创建命名管道,所以不要忘记这一点。

但是管道删除不是重点,重点是我们的共享内存其实是通过引用计数来判断是否需要删除共享内存的,所以新接口来了:shmdt.

它所提供的功能就是把我们虚拟地址和共享内存的联系解开,再对管理者的计数--。

运行效果
server可以成功创建并且管道也能创建。

client也可以找到目标成功建立链接

然后假设我们要每写两个字符才读一次
client:

server:

结果:

一旦我们的写入方(client)链接上,它就开始写写写,然后每两个字符唤醒一下管道,然后管理者(server)就开始读读读,最后读完自动析构回收。
总结
命名管道也许像个懒驴一样抽一下走一下效率有点低(和共享内存比),但是共享内存快就一定好吗,未必,所以我们把它们相结合,实现又快又稳的方法进行读写,完全可以按照我们的实际情况,设置条件实现全自动读取写入。