Linux进程间通信--共享内存

共享内存是什么?

  • 共享内存区域是被多个进程共享的一部分物理内存。如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信。共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。这块共享虚拟内存的页面,出现在每一个共享该页面的进程的页表中。但是它不需要在所有进程的虚拟内存中都有相同的虚拟地址。

共享内存实现进程间通信与其他IPC比较:

  • 共享内存实现进程通信的优点:
    共享内存是进程通信方式中最快速的方式之一,它的快速体现在,为数据共享而进行的复制非常少。这里举例来说,使用消息队列时,一个进程向消息队列写入消息时,这里有一次数据的复制,从用户空间到内核空间。而另一个进程读取消息的时候,又有一次数据的复制,从内核空间到用户空间,这无疑是耗费时间与资源的。然而共享内存的存在则无需这两次复制,进程是从它们各自的地址空间直接访问共享的内存区段的。
  • 缺点:
    还是拿消息队列来对比,消息队列已经实现了对自身读写的保护,然而共享内存需要我们开发者自己来实现,这无疑增加了开发的难度

共享内存有关函数:

  • key_t ftok(const char *pathname, int proj_id);//用某种方法获取key,第一个参数,和第二个参数都是自己随便给,(第一个参数必须是已存在且可以访问的文件名),只要不和系统重复就行。

  • int shmget(key_t key, size_t size, int shmflg);//第二个参数为创建的共享内存段大小(以页(4k=4096byte)为单位,按页配,如果大小为4097,会分配两页,但是只能用一页),单位为字节;第三个参数为选项(IPC_CREATE和IPC_EXCL),如果两个选项都选,表示如果共享内存段不存在,则创建,返回共享内存段的标识符,如果存在会报错(返回-1);如果只选IPC_CREATE,表示如果共享内存段不存在,会报错,存在返回共享内存段标识符。两个选项目的就i是,一个创建,一个获取。

  • void *shmat(int shmid, const void *shmaddr, int shmflg);//将共享内存段连接到进程地址空间(即将物理内存上的共享内存段映射到该进程虚拟地址空间),第一个参数为共享内存段的标识符,第二个参数指定连接地址(通常设置为NULL),第三个参数通常设置为0. 返回值为该共享内存段的指针(与malloc类似)。

  • int shmdt(const void *shmaddr);//将共享内存段从当前进程脱离,参数为上个函数的返回值。

  • int shmctl(int shmid, int cmd, struct shmid_ds *buf);//用于控制共享内存,第二个参数如果为IPC_RMID,第三个参数为NULL表示删除(释放)该共享内存段。

命令查看删除共享内存段

  • 查看
ipcs -m 
  • 删除
ipcrm -m shmid

实现共享内存

  • server.c
    这里写图片描述
  • cilent.c
    这里写图片描述
  • Makefile
    这里写图片描述

共享内存实现进程间通信的原理

  • 共享内存就是物理内存上的一块空间,多个进程可以通过相同的方式得到相同的键值,再通过shmget()传入相同的键值获得相同的共享内存段,再通过shmat()将共享内存段的地址(物理地址)映射到自己的虚拟地址空间,这样就可以直接将信息写入到共享内存(物理地址),其他有相同共享内存标识符的进程也可以向共享内存段写入信息,或者读取信息。这样就实现了进程间通信的目的。

猜你喜欢

转载自blog.csdn.net/virgofarm/article/details/80406482