【Linux】IPC

111 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情

IPC

  1. 简介 进程间通信的三种主要方式有:

    • 管道: 使用最简单
    • 信号:开销最小
    • 共享映射区:无血缘关系
    • 本地套接字:最稳定

1. mmp

  • 简介

    • mmp函数
    • 借组共享内存放磁盘文件,借组指针访问磁盘文件
    • 父子进程、血缘关系进程 通信
    • 匿名映射区
  • 函数

     #include <sys/mman.h>
     ​
     void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
    

    函数返回的是:创建映射区的首地址,失败返回MAP_FAILED

    • 参数

      • addr:直接传入 NULL
      • length:欲创建映射区的大小
      • prot映射区权限PORT_READ、PORT_WRITE、PORT_READ|PORT_WRITE
      • flags:标志参数。是否会将映射区所作的修改反映到物理设备(磁盘)上。    a).MAP_SHARED:会    b). MAP_PRIVATE:不会
      • fd:用来创建映射区的文件描述符
      • offset:映射文件的偏移。(4k的整倍数)
    • 注意事项

      • 不能创建0字节大小的映射区,因此新创建出来的文件不能用于创建映射区
      • 权限    a). 创建映射区的权限,要小于等于打开文件权限    b). 创建映射区的过程中,隐含着一次对打开文件的读操作。
      • offset: 必须是4k的整数倍,mmu创建的最小大小就是4k
      • 关闭fd,对mmap无影响。
  • 父子进程通信 父子进程之间的也可以通过mmap建立的映射区来完成数据通信。但是mmap函数的flags标志位应该设置flags=MAP_SHARED

    • 父子进程共享:

      • 打开的文件描述符
      • mmap建立的映射区。
    • 匿名映射 由于mmap需要在进程之间通信时,需要借组一个文件描述符,但是对应的文件仅仅在通信期间存在,为了省略这一临时文件,产生匿名映射。

      • Linux独有的方法:宏MAP_ANONYMOUS/MAP_ANONchar* pmem = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);

      • 通用的方法:

         int fd = open("/dev/zero", O_RDWR);
         char* pmem = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);  
        

        使用的是一个文件/dev/zero完成。

  • mmap实现无血缘关系进程间通信 实际上mmp是内核借助文件帮我们创建了一个映射区。多个进程利用该映射区完成书的传递。由于内核是多进程共享,因此无血缘关系的进程间也可以使用mmap完成数据通信。