• 【Linux 应用编程】进程管理


    IPC(InterProcess Communication,进程间通信)是进程中的重要概念。Linux 进程之间常用的通信方式有:

    • 文件:简单,低效,需要代码控制同步
    • 管道:使用简单,默认阻塞
      • 匿名管道 pipe:只存在于内核缓冲区,只能用于有血缘关系的进程
      • 有名管道 FIFO:在文件系统中存在,可用于无血缘关系的进程
    • 信号量:使用复杂,但开销小,操作系统本身支持信号量
    • 内存映射区 mmap:进程有无血缘关系都可以
    • 本地套接字 socket:稳定可靠

    共享内存

    通过共享内存,两个不相干的进程可以使用同一段逻辑内存。这块内存通常也是同一段物理内存。每个进程都把这段共享内存连接到自己的地址空间中,直接访问。

    共享内存是进程间传递数据的常用方式,非常高效。

    共享内存的使用

    POSIX 共享内存区的使用包含四个步骤:

    • 调用 shm_open 创建一个新的共享内存区对象(或打开一个以存在的共享内存区对象)
    • 调用 mmap 把这个共享内存区映射到调用进程的地址空间
    • 调用 munmap() 取消共享内存映射
    • 调用 shm_unlink()函数删除共享内存段

    在编译 POSIX 共享内存应用程序时需要加上 -lrt 参数。

    shm_open 函数

    shm_open() 函数用来打开或者创建一个共享内存区,两个进程可以通过给 shm_open() 函数传递相同的名字以达到操作同一共享内存的目的。

    新建的共享内存区大小默认为 0,需要使用 ftruncate 函数设置大小才能使用。

    函数原型:

    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    int shm_open(const char *name, int oflag, mode_t mode);
    

    返回值:
    成功返回创建或打开的共享内存描述符(与文件描述符相同作用),失败返回-1。

    参数:

    • name:创建的共享内存的名称,其它进程可以根据这个名称来打开共享内存
    • oflag:以下值的或值:
      • O_RDONLY:共享内存以只读方式打开;
      • O_RDWR:共享内存以可读写方式打开;
      • O_CREAT:共享内存不存在才创建;
      • O_EXCL:如果指定了 O_CREAT,但共享内存已经存在时返回错误;
      • O_TRUNC:如果共享内存已存在则将大小设置为 0;
    • 参数 mode 只有指定 O_CREAT 才有效指出,指出共享内存的权限,与 open()函数
      类似。

    ftruncate 函数

    新建的共享内存默认大小为 0,需要设置共享内存大小。ftruncate()函数可用来调整文件或者共享内存的大小。

    函数原型:

    #include <unistd.h>
    #include <sys/types.h>
    int ftruncate(int fd, off_t length);
    

    函数成功返回 0,失败返回-1。
    参数:

    • fd:需要调整的共享内存或者文件
    • length:大小

    mmap 函数

    共享内存创建或打开后,是不能在进程内直接使用的。需要先映射到当前进程的地址空间。

    函数原型:

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

    参数:

    • addr:指向映射存储区的起始地址,通常将其设置为 NULL,这表示由系统选择该
      映射区的起始地址;
    • len:映射的字节数;
    • prot:对映射存储区的保护要求,对指定映射存储区的保护要求不能超过文件 open
      模式访问权限。它可以为以下值的或值:
      • PROT_READ:映射区可读);
      • PROT_WRITE:映射区可写;
      • PROT_EXEC:映射区可执行;
      • PROT_NONE:映射区不可访问。
    • flag:映射标志位,可为以下值的或值:
      • MAP_FIXED:返回值必须等于 addr。因为这不利于可移植性,所以不鼓励使用此标志;
      • MAP_SHARED:多个进程对同一个文件的映射是共享的,一个进程对映射的
        内存做了修改,另一个进程也会看到这种变化;
        MAP_PRIVATE:多个进程对同一个文件的映射不是共享的,一个进程对映射
        的内存做了修改,另一个进程并不会看到这种变化。
    • fd:要被映射的文件描述符或者共享内存描述符;
    • offset:要映射字节在文件中的起始偏移量。

    munmap 函数

    函数原型:

    #include <sys/mman.h>
    int munmap(void *addr, size_t length);
    

    函数成功返回 0,否则返回-1;
    参数:

    • addr 为 mmap()函数返回的地址
    • length 是映射的字节数。取消映射后再对映射地址访问会导致调用进程收到 SIGSEGV 信号。

    shm_unlink 函数

    函数原型:

    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    int shm_unlink(const char *name);
    

    函数成功返回 0,否则返回-1。

    示例

    两个没有血缘关系的进程,也可以使用共享内存进行进程间通信:

    
    
  • 相关阅读:
    如何编写属于自己的事件集合
    Android文件操作(可应用于JAVA)
    Share Point 2007 copy webservices overwrite exist file
    cnBlog的windows live writer 客户端配置
    VS 2012 找回消失的“创建单元测试”
    Oracle函数参考
    哲理小故事(一)
    输入框信息提示
    实现记住用户登陆名
    常用正则表达式
  • 原文地址:https://www.cnblogs.com/kika/p/10851499.html
Copyright © 2020-2023  润新知