进程间通信
进程:
进程:是正在运行的程序的实例,进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
进程分为两种类型:操作系统进程、用户进程。
系统进程:是操作系统自身运行时的内核类进程。
用户进程:即非内核类进程,不是操作系统自身的进程,而是想要实现某些功能,用户自己去启动的程序产生的进程。
进程间通信:
除了单机上的多个进程可能需要进程间通信,多计算机之间的进程有时候也需要进行进程间的通信。这很常见,例如:本机上的QQ客户端进程需要和腾讯的QQ服务器上的进程进行数据传输,浏览器浏览网页时,浏览器进程需要和网页所在的服务端进程进行数据传输,等等。
从广义上讲,只要进程间能共享数据或传递数据就算是进程间通信。而进程间的通信方式有很多,如:有名管道、无名管道、共享内存、消息队列、信号、套接字、信号量等等。
管道:
管道分为有名管道与无名管道(匿名管道)两种,管道只能承载无格式的字节流。
无名管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程(父子进程关系之)间使用。当一个进程创建了一个管道,并调用 fork 创建自己的一个子进程后,父进程关闭读管道端,子进程关闭写管道端,这样提供了两个进程之间数据流动的一种方式。
有名管道也是一种半双工的通信方式,但是它允许无亲缘关系进程间的通信,因为它创建了一个类型为管道的设备文件,使用这个设备文件就可以进行不同进程间的通信通信。
共享内存:
共享内存就是映射一段能被进程之间共享的内存。这段内存由一个进程创建,但是多个进程都可以共享访问,是最快的一种进程间通信的方式(不需要从用户态到内核态的切换)。它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制配合使用,来实现进程间的同步和通信。
消息队列:
消息队列是消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式的字节流,消息到了就放进去,需要的时候去取。与命名管道相比:消息队列的优势在于,它独立于发送和接收线程,消除了在同步命名管道的打开和关闭时可能产生的一些困难。
消息队列是 UNIX 下不同进程之间可实现共享资源的一种机制,UNIX 允许不同进程将格式化的数据流以消息队列形式发送给任意进程。对消息队列具有操作权限的进程都可以使用 msget 完成对消息队列的操作控制。通过使用消息类型,进程可以按任何顺序读信息,或为消息安排优先级顺序。
信号与信号量:
信号是进程之间唯一的异步通信机制,且是一种比较复杂的通信方式。信号的主要来源主要有硬件来源(入键盘操作ctrl + C) 和软件来源(如kill命令),信号传递的信息比较少,主要用于通知进程某个时间已经发生。比如利用kill pid,可以让系统优雅停机。
信号量是一个计数器,可以用来控制多个进程对资源的访问,通常作为一种锁机制,防止某个进程正在访问共享资源,其他进程也访问资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
套接字:
socket套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。