进程通信专题之 共享内存

 

上一期我们讲到了信号通信,在信号通信中,我们只需要掌握三部分即可,即信号的发送,信号的的接收,信号的处理。和信号通信类似,我们在共享内存中只需要了解共享内存的创建,共享内存的映射,共享内存的删除。就可以使用共享内存来进行通信了。

那么?什么是共享内存呢?

       共享内存是被多个进程共享一部分物理内存,共享内存是进程间共享数据最快的办法,因为一个进程向共享内存中写了数据,那么共享的这个区域的所有进程就可以立刻看到这里的数据。

共享内存有什么特点呢?

       共享内存被创建以后,一直存在于内核中,直到被删除或者系统关闭,并且读取后,内容仍在其共享内存中。

第一部分,共享内存的创建

        我们可以使用shmget来创建一个共享内存。函数原型如下:


 

我们来通过一个例子来了解下这个函数:

 

编译并运行,在终端输入命令ipcs -m,可以看见我们创建的共享内存,返回值为共享内存IPC的ID号。因为我们使用的是IPC_PRIVATE,所以共享内存的key都是0。

 

上图中,nattch表示连接数目,dest表示共享内存段已经被删除了,但是还有程序在连接他。这个key值还可以用ftok函数来创建,如果我们使用IPC_PRIVATE这个参数,我们的key都是0,这样我可以进行有亲缘关系的进程通信,如果我们使用ftok函数来创建,可以进行没有亲缘的进程之间的通信:

 

第二部分,共享内存的映射

       我们在用shmget函数在内核创建一个对象,即开辟一个缓存。 为了方便我们对共享内存进行读写操作,我们需要把我们开辟的缓存映射到用户空间去。我们可以使用shmat函数:

 


第三部分,共享内存的删除

       因为我们的共享内存有个特点,共享内存被创建以后,一直存在于内核中,直到被删除或者系统关闭,并且读取后内容仍在其共享内存中,如果想删除共享内存,我们可以使用shmctl和shmdt。

       shmdt函数将我们映射的地址删除,删除的是我们映射在用户空间的地址。函数原型如下:

 

 

如果想删除内核中的对象,我们可以使用shmctl删除共享内存对象。函数原型如下:

 

 

第四部分,共享内存实例

程序目的:实现父子进程间的通信

程序思路

        为了复习一下上一期的内容,我们在实例中加上信号通信,信号通信有疑惑的地方大家可以看上一期文章呢,因为不确定父子进程是谁先运行的,所以我们在父进程中延迟一会,保证子进程先运行,这样我们父进程发信号给子进程就不会导致子进程停止,父进程往共享内存里面写完数据后,发信号给子进程,子进程收到信号后开始读共享内存里面的数据。子进程读完数据以后,删除掉进程和内核里面的共享内存。

 

编译并运行:

 

 

总结:

       和信号通信一样,只要我们明确了共享内存创建,映射,删除这个流程,共享内存的知识点很容易就掌握了。

 

转自:http://www.topeetboard.com

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值