每一个进程各自有不一样的用户地址空间,任何一个进程的变量在另外一个进程中都是看不到的,因此进程之间要交换数据必须经过内核,在内核中开辟出一块缓冲区。一个进程把本身的数据从用户空间拷贝到内核缓冲区,另外一个进程再从内核缓冲区把数据读走。内核提供的这种机制称为进程间通讯(IPC,Inter Process Communication)网络
Linux进程间基本的通讯方式主要有:管道(pipe)(包括匿名管道和命名管道)、信号(signal)、消息队列(queue)、共享内存、信号量和套接字。异步
下面逐渐介绍这几种方式:函数
1.管道:管道的实质是一个内核缓冲区,管道的做用正如其名,须要通讯的两个进程在管道的两端,进程利用管道传递信息。管道对于管道两端的进程而言,就是一个文件,可是这个文件比较特殊,它不属于文件系统而且只存在于内存中。设计
管道依据是否有名字分为匿名管道和命名管道(有名管道),这两种管道有必定的区别。队列
匿名管道有几个重要的限制:进程
命名管道容许没有亲缘关系的进程进行通讯。命名管道不一样于匿名管道之处在于它提供了一个路径名与之关联,这样一个进程即便与建立有名管道的进程不存在亲缘关系,只要能够访问该路径,就能经过有名管道互相通讯。事件
2.信号:信号是软件层次上对中断机制的一种模拟,是一种异步通讯方式,进程没必要经过任何操做来等待信号的到达。信号能够在用户空间进程和内核之间直接交互,内核能够利用信号来通知用户空间的进程发生了哪些系统事件。ip
信号来源:内存
信号事件的发生有两个来源:硬件来源,好比咱们按下了键盘或者其它硬件故障;软件来源,最经常使用发送信号的系统函数是kill, raise, alarm和setitimer以及sigqueue函数,软件来源还包括一些非法运算等操做。资源
进程对信号的响应:
进程能够经过三种方式来响应信号:(1)忽略信号,即对信号不作任何处理,可是有两个信号是不能忽略的:SIGKLL和SIGSTOP;(2)捕捉信号,定义信号处理函数,当信号发生时,执行相应的处理函数;(3)执行缺省操做,Linux对每种信号都规定了默认操做。
3.消息队列:消息队列是消息的链表,具备特定的格式,存放在内存中并由消息队列标识符标识,而且容许一个或多个进程向它写入与读取消息
4.共享内存:使得多个进程能够能够直接读写同一块内存空间,是针对其余通讯机制运行效率较低而设计的。
为了在多个进程间交换信息,内核专门留出了一块内存区,能够由须要访问的进程将其映射到本身的私有地址空间。进程就能够直接读写这一块内存而不须要进行数据的拷贝,从而大大提升效率。
须要注意的是:共享内存并未提供同步机制,在一个进程结束对共享内存的写操做以前,并没有自动机制能够阻止另二个进程开始对它进行读取。因此,咱们一般须要用其余的机制来同步对共享内存的访问。
5.信号量:信号量实质上就是一个标识可用资源数量的计数器,它的值老是非负整数。而只有0和1两种取值的信号量叫作二进制信号量(或二值信号量),可用用来标识某个资源是否可用。
6.套接字:套接字是更为基础的进程间通讯机制,与其余方式不一样的是,套接字可用于不一样机器之间的进程间通讯。
有两种类型的套接字:基于文件的和面向网络的。
(1).Unix套接字是基于文件的,而且拥有一个“家族名字”--AF_UNIX,它表明地址家族(address family):UNIX。
(2).第二类型的套接字是基于网络的,它也有本身的家族名字--AF_INET,表明地址家族(address family):INTERNET
无论采用哪一种地址家族,都有两种不一样的套接字链接:面向链接的和无链接的。
(1)面向链接的套接字(SOCK_STREAM):进行通讯前必须创建一个链接,面向链接的通讯提供序列化的、可靠地和不重复的数据交付,而没有记录边界。
这意味着每条信息能够被拆分红多个片断,而且每一个片断都能确保到达目的地,而后在目的地将信息拼接起来。
实现这种链接类型的主要协议是传输控制协议(TCP)。
(2)无链接的套接字(SOCK_DGRAM):在通讯开始以前并不须要创建链接,在数据传输过程当中并没有法保证它的顺序性、可靠性或重复性。
然而,数据报确实保存了记录边界,这就意味着消息是以总体发送的,而并不是首先分红多个片断。
因为面向链接的套接字所提供的保证,所以它们的设置以及对虚拟电路链接的维护须要大量的开销。然而,数据报不须要这些开销,即它的成本更加“低廉”
实现这种链接类型的主要协议是用户数据报协议(UDP)。