进程间通信简介

进程间通信

Linux几乎支持全部UNIX进程间通信方法,包括管道(有名管道和无名管道)、消息队列、共享内存、信号量和套接字。其中前四个属于同一台机器下进程间的通信,套接字则是用于网络通信。

管道

  • 无名管道

    • 无名管道特点:

      • 无名管道是一种特殊的文件,这种文件只存在于内存中。

      • 无名管道只能用于父子进程或兄弟进程之间,必须用于具有亲缘关系的进程间的通信。

      • 无名管道只能由一端向另一端发送数据,是半双工方式,如果双方需要同时收发数据需要两个管道。

    • 相关接口:

      • int pipe(int fd[2]);

        • fd[2]:管道两端用fd[0]和fd[1]来描述,读的一端用fd[0]表示,写的一端用fd[1]表示。通信双方的进程中写数据的一方需要把fd[0]先close掉,读的一方需要先把fd[1]给close掉。
  • 有名管道:

    • 有名管道特点:

      • 有名管道是FIFO文件,存在于文件系统中,可以通过文件路径名来指出。

      • 无名管道可以在不具有亲缘关系的进程间进行通信。

    • 相关接口:

      • int mkfifo(const char *pathname, mode_t mode);

        • pathname:即将创建的FIFO文件路径,如果文件存在需要先删除。

        • mode:和open()中的参数相同。

消息队列

共享内存

进程可以将同一段共享内存连接到它们自己的地址空间,所有进程都可以访问共享内存中的地址,如果某个进程向共享内存内写入数据,所做的改动将立即影响到可以访问该共享内存的其他所有进程。

  • 相关接口

    • 创建共享内存:int shmget(key_t key, int size, int flag);

      成功时返回一个和key相关的共享内存标识符,失败范湖范围-1。

      • key:为共享内存段命名,多个共享同一片内存的进程使用同一个key。

      • size:共享内存容量。

      • flag:权限标志位,和open的mode参数一样。

    • 连接到共享内存地址空间:void *shmat(int shmid, void *addr, int flag);

      返回值即共享内存实际地址。

      • shmid:shmget()返回的标识。

      • addr:决定以什么方式连接地址。

      • flag:访问模式。

    • 从共享内存分离:int shmdt(const void *shmaddr);

      调用成功返回0,失败返回-1。

      • shmaddr:是shmat()返回的地址指针。
  • 其他补充

    共享内存的方式像极了多线程中线程对全局变量的访问,大家都对等地有权去修改这块内存的值,这就导致在多进程并发下,最终结果是不可预期的。所以对这块临界区的访问需要通过信号量来进行进程同步。

    但共享内存的优势也很明显,首先可以通过共享内存进行通信的进程不需要像无名管道一样需要通信的进程间有亲缘关系。其次内存共享的速度也比较快,不存在读取文件、消息传递等过程,只需要到相应映射到的内存地址直接读写数据即可。

信号量

在提到共享内存方式时也提到,进程共享内存和多线程共享全局变量非常相似。所以在使用内存共享的方式是也需要通过信号量来完成进程间同步。多线程同步的信号量是POSIX信号量, 而在进程里使用SYSTEM V信号量。

  • 相关接口

    • 创建信号量:int semget(key_t key, int nsems, int semflag);

      创建成功返回信号量标识符,失败返回-1。

      • key:进程pid。

      • nsems:创建信号量的个数。

      • semflag:指定信号量读写权限。

    • 改变信号量值:int semop(int semid, struct sembuf *sops, unsigned nsops);

      我们所需要做的主要工作就是串讲sembuf变量并设置其值,然后调用semop,把设置好的sembuf变量传递进去。

      struct sembuf结构体定义如下:

      struct sembuf{
          short sem_num;
          short sem_op;
          short sem_flg;
      };

      成功返回信号量标识符,失败返回-1。

      • semid:信号量集标识符,由semget()函数返回。

      • sops:指向struct sembuf结构的指针,先设置好sembuf值再通过指针传递。

      • nsops:进行操作信号量的个数,即sops结构变量的个数,需大于或等于1。最常见设置此值等于1,只完成对一个信号量的操作。

    • 直接控制信号量信息:int semctl(int semid, int semnum, int cmd, union semun arg);

      • semid:信号量集标识符。

      • semnum:信号量集数组上的下标,表示某一个信号量。

      • arg:union semun类型。

辅助命令

ipcs命令用于报告共享内存、信号量和消息队列信息。

  • ipcs -a:列出共享内存、信号量和消息队列信息。

  • ipcs -l:列出系统限额。

  • ipcs -u:列出当前使用情况。

套接字

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页