刚请完婚假,请假期间做了些技术总结,其中一个就是Linux进程间通信方式的总结。

Linux提供了多种进程间通信的方式,列举如下:

  • PIPE(管道)
  • FIFO(先进先出,也称为有名管道)
  • domain_socket(域套接字)
  • XSI-semaphore(XSI信号量)
  • XSI-message_queue(XSI消息队列)
  • XSI-shared_memory(XSI共享内存)
  • POSIX-semaphore(POSIX信号量)
  • mutex(互斥量)

其中semaphore和互斥量虽然是进程或线程间的同步方式,但是同步其实本质上也是通信的一种,所以这里也一并列出来。

PIPE

管道是最古老也是最常用的进程间通信方式,我们在Linux命令行中使用的ls | grep crond就是使用管道将前一个进程的输出重定向为后一个进程的输入。管道主要的缺点是:

  1. 只能用于父子或其它有共同祖先的进程之间;
  2. 是单工通信。

FIFO

为了克服管道只能用于父子进程间的缺点,引入了有名管道,又称为先入先出队列。FIFO的操作方式与普通文件类似,但是必须同时有写端和读端才可操作。

相对于PIPE,FIFO的主要改进是:

  1. 可以用于任意两个进程之间
  2. 可以通过FIFO文件的属性来控制访问权限

Domain Socket

域套接字是一种类似于网络套接字的通信方式,但是专门用于同一台主机的两个进程之间,它是一种双工的通信方式。

XSI Semaphore

XSI是X/Open System Interfaces的缩写,是一种系统接口的标准,它规定了三种通信方式,即semaphore、message queue、shared memory,它们有一致的编程接口。Linux系统上可以使用两种形式的信号量,一种是这里说的XSI_semaphore,还有一种是POSIX_semaphore,后面再解释什么是POSIX_semaphore。

在非必须的情况下,个人不推荐使用XSI进程间通信的方,因为它比较复杂。除了共享内存之外,另外两种XSI进程间通信方式都有其它的替代方法。XSI进程间通信的大致流程如下:

  1. 两个进程获取一个key
  2. 两个进程使用这个key来获取进程间通信的ID
  3. 两个进程进行进程间通信
  4. 其中一个进程释放进程间通信的ID

最麻烦的地方在于,进程间通信的ID不会随着进程结束自动释放,必须要手动释放。

信号量用于保护不同进程或线程对于有限资源的访问,在进程访问资源前,需要获取信号量,访问结束后释放信号量。当信号量当前值等于0时,获取信号量的进程必须等待,直到有其它进程释放信号量。

XSI Message Queue

消息队列是另一种XSI进程间通信方式,通过两个进程读写同一个内核消息队列来实现进程间通信。

XSI Shared Memory

共享内存是一种最高效的进程间通信方式,直接将一片内存同时映射到两个进程中,然后两个进程读写这片内存即可实现进程间通信。它的代价就是要自己进程同步操作防止出现数据不一致的情况。

POSIX Semaphore

相对于XSI Semaphore,POSIX Semaphore要容易使用的多。

Mutex

一般来说mutex只用于线程间同步,但是通过将一个mutex变量映射到两个不同进程的地址空间中,并设置mutex的进程间共享的属性,也可以用于进程间通信,不过比较麻烦就是啦。如果对于mutex有特殊的爱好,也可以使用的哦。

代码

所有的代码已上传到https://github.com/clpsz/linux-ipcs。虽然每个目录都只有一个main函数,但是代码中使用fork创建了两个进程,不过除了PIPE之外,其它的进程间通信方式并不限于父子进程之间,使用fork只是为了方便测试。

Linux进程间通信总结的更多相关文章

  1. Linux进程间通信(一): 信号 signal()、sigaction()

    一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...

  2. Linux进程间通信(二):信号集函数 sigemptyset()、sigprocmask()、sigpending()、sigsuspend()

    我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程.那么我们应该如何设定我 ...

  3. Linux进程间通信(三):匿名管道 popen()、pclose()、pipe()、close()、dup()、dup2()

    在前面,介绍了一种进程间的通信方式:使用信号,我们创建通知事件,并通过它引起响应,但传递的信息只是一个信号值.这里将介绍另一种进程间通信的方式——匿名管道,通过它进程间可以交换更多有用的数据. 一.什 ...

  4. Linux进程间通信(四):命名管道 mkfifo()、open()、read()、close()

    在前一篇文章—— Linux进程间通信 -- 使用匿名管道 中,我们看到了如何使用匿名管道来在进程之间传递数据,同时也看到了这个方式的一个缺陷,就是这些进程都由一个共同的祖先进程启动,这给我们在不相关 ...

  5. Linux进程间通信(五):信号量 semget()、semop()、semctl()

    这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信 -- 信号.下面 ...

  6. Linux进程间通信(六):共享内存 shmget()、shmat()、shmdt()、shmctl()

    下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...

  7. Linux进程间通信(七):消息队列 msgget()、msgsend()、msgrcv()、msgctl()

    下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信 -- 使用命名管道 一.什么是消息队列 消息队列提 ...

  8. Linux进程间通信(九):数据报套接字 socket()、bind()、sendto()、recvfrom()、close()

    前一篇文章,Linux进程间通信——使用流套接字介绍了一些有关socket(套接字)的一些基本内容,并讲解了流套接字的使用,这篇文章将会给大家讲讲,数据报套接字的使用. 一.简单回顾——什么是数据报套 ...

  9. [转]Linux进程间通信——使用消息队列

    点击此处阅读原文 另收藏作者ljianhui的专栏初学Linux 下面来说说如何使用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linu ...

  10. Linux 进程间通信(二) 管道

    Linux 进程间通信-管道 进程是一个独立的资源分配单位,不同进程之间的资源是相互独立的,没有关联,不能在一个进程中直接访问另一个进程中的资源.但是,进程不是孤立的,不同的进程之间需要信息的交换以及 ...

随机推荐

  1. Werkzeug源码阅读笔记(四)

    今天主要讲一下werkzeug中的routing模块.这个模块是werkzeug中的重点模块,Flask中的路由相关的操作使用的都是这个模块 routing模块的用法 在讲解模块的源码之前,先讲讲这个 ...

  2. java反射机制(笔记)

    java反射机制就是获取出class的相应方法 例如 获取构造函数: 模版: Class test = Class.forName("cn.test.Person");//得到相应 ...

  3. asp.net core + angular2

    asp.net core + angular2 的环境配置 国内整个对 asp.net core  和 angular2这些新出来的关注度不是太好.跟国外比很大差距. 我在试着去做这个整合的时候也碰到 ...

  4. selenium webdriver 学习笔记(一)

    selenium webdriver 第一个脚本: #coding = utf-8 from selenium import webdriver import time url = "htt ...

  5. J2SE知识点摘记(九)

    1.         线程操作的一些方法 方法名称              方法说明 public static int activeCount()             返回线程组中目前活动的线 ...

  6. Cortex-M3学习日志(五) -- DAC实验

    终于逮了个忙里偷闲的机会,就再学一下LPC1768的外围功能吧,循序渐进是学习的基本规则,也许LPC1768的DAC与8位单片机16位单片机里面集成的DAC操作类似,但是既然这是懒猫的学习日志,就顺便 ...

  7. Delphi中运行时改变panel的位置及大小(WM_SysCommand消息配合参数使用,很奇妙) good

    procedure TForm1.pnl1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Inte ...

  8. Android系统Recovery工作原理之使用update.zip升级过程---updater-script脚本语法简介以及执行流程(转)

    目前update-script脚本格式是edify,其与amend有何区别,暂不讨论,我们只分析其中主要的语法,以及脚本的流程控制. 一.update-script脚本语法简介: 我们顺着所生成的脚本 ...

  9. android在桌面弹出一个窗口

    android在桌面弹出一个窗口 遇到了这种需求,要和iPhone一样的效果. 下面是简单实现功能,优化和美化部分,有时间慢慢搞. 方法应该有不少吧,我用的是弹出一个activity,将这个activ ...

  10. linux 获取文件系统信息(磁盘信息)

    源代码例如以下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <s ...