我们学会了争抢,学会了占有,学会了排斥,却唯独没有学会分享
共享内存是linux中最为重要的IPC及硬件组件通信方式之一,本文将针对共享内存基本使用方法、常见共享内存模型以及共享内存并发访问保护等方面进行总结。
共享内存使用
linux下实现共享内存的方式有很多,本节将基于SYS V创建共享内存实现IPC通信,并总结一些常见的模型
基本使用方法(SYS V)
SYS V的共享内存即对应内核代码linux/ipc/shm.c
,使用方式比较奇怪,以文件作为中介,使用attach和detach的方式进行映射和解映射,我在这里封装了一套接口用于创建和销毁共享内存,其中创建的代码如下:
1 | void *AttachShm(const char *fileName) |
销毁的代码如下:
1 | int DetachShm(char *buf) |
基本模型1:不带保护的生产者/消费者问题
在创建共享内存后,我们就可以进行进程间通信,一个基本的读写者模型如下:
1 | /* Create and init a sensor */ |
当然,上面这个读写模型没有并发保护,存在并发问题,运行结果如下:
1 | duan@ubuntu:~/Code/OS/memory/cmake/src$ ./server 123 |
两个终端,写者写了10次,但是读者只读了一次,读者在读的时候没有阻止写操作,读取到的次数是随机的,无法使用。
基本模型2:由单个信号量进行读写保护的生产者/消费者问题
现在我们使用信号量对共享内存的访问进行并发保护,我们创建两个信号量,分别用于生产者和消费者,基本逻辑如下:
- 当生产者开始生产时,需要wait(reader),当生产完毕后,需要post(writer)
- 当消费者开始消费时,需要wait(writer),当消费完毕后,需要post(reader)
1 | #define SEM_WRITER_FNAME "/writer" |