进程以及进程通讯(IPC)类型

这里用我有限的知识来解释同时参考了一些其余博主的子类,但愿能给与一部分入门的朋友一个清晰的理解,有问题之处还请指出linux

 

首先简单谈一下什么是进程程序员

答:进程是装入内存运行的程序段,是许多的系统对象拥有权的集合,换句你们常常引用的话说进程是资源分配的基本单位编程

举例来讲,咱们的浏览器程序存放在C盘的某个位置,这时它只是硬盘上的程序。每次咱们打开一个浏览器的时候,这个程序就会被装入内存中去,进行一系列初始化(进程控制块PCB的初始化,包括进程计数器,进程状态,CPU命令,寄存器等等)。此时咱们看到了浏览器打开并显示网页,此时这就是一个运行中的进程,咱们能够打开任务管理器看到许许多多运行的进程。windows


为何说进程拥有许多系统对象?浏览器

答:刚才说了,进程是装入内存的程序段,那进程的运行势必涉及到内存的分配(包括堆栈,文本区,数据区等,这里是参考了C语言程序的内存分配),而进程所占用的内存中就可能会有文件句柄,DLL模块(在可执行程序运行时才载入内存的代码),上下文等。安全

这里,咱们顺便说一下线程,你们记住线程是CPU运行调度的基本单位,线程必须被包含在进程中,一个进程能够有不少线程(至少有一个),这些线程共享进程的许多资源(如栈,寄存器)。(关于进程与线程的优缺点,多线程的东西会在以后的博客里写)。服务器

 

什么是进程通讯?为何要通讯?网络

答:进程通讯(IPC),即Inter-ProcessCommunication,字面上理解就是进程之间的通讯多线程

这里举一个不一样主机的进程通讯,比较容易理解。你电脑上打开一个网页,就能看到各类文字图片,这些图片是哪里来的?如何获取的?咱们上面说打开的浏览器就是一个进程,那浏览器获取别处的图片资源就是一种通讯的方式来拿到想要的东西的。浏览器向服务器发送请求获取资源就是一种靠套接字来进行的进程通讯,这种通讯经过一台主机的应用层端口以及Socket下发到运输层(TCP),再通过下面的网络层,数据链路层,物理层(这是计算机网络5层模型)传输到另外一台机器的socket,最后服务器获取到该信息,实现进程间通讯。一句话说,A主机的浏览器经过socket与另外一台B主机的进程进行通讯交流。app

 

 

进程属于内核的基本功能,因此不一样的操做系统在实现进程通讯有必定的区别,不过想通之处也仍是不少的。

其实,可能有不少同窗和朋友和我一开始理解的同样,认为IPC只有消息传递和共享内存两种(没错,操做系统书上就是这么写的),可后来我发现消息传递具体是什么,有什么特色,我都说不太清~因此稍微研究了下

咱们能够这样理解:

IPC只是按形式上能够分为消息传递,共享内存,同步。

(下面是用linux的IPC举例)

消息传递就包括,管道,FIFO命名管道,消息队列

共享内存,包括匿名与具名的,

同步,包括互斥量,读写锁,信号量等。

咱们能够把每一种IPC都拿出来单独做比较。

 

首先先大体说一下共享内存,管道的概念

其原理就是将一份物理内存映射到不一样进程各自的虚拟地址空间,使每个进程均可以读取这份数据,来实现通讯,由于是直接经过内存操做,因此是一种很是高效的通讯方式。

管道(Pipe)是一种具备两个端点的通讯通道:有一端句柄的进程能够和有另外一端句柄的进程通讯。管道能够是单向-一端是只读的,另外一端点是只写的;也能够是双向的一—管道的两端点既可读也可写。

 

下面简单介绍一下Windows与Linux的进程通讯以及比较:(这里主要参考了 coolmeme 的博客)

Windows:

1.    文件映射

文件映射(Memory-Mapped Files)能使进程把文件内容看成进程地址区间一块内存那样来对待。所以,进程没必要使用文件I/O操做(正常来讲须要用输入输出流来读写文件ioStream),只需简单的指针操做就可读取和修改文件的内容。

Win32API容许多个进程访问同一文件映射对象,各个进程在它本身的地址空间里接收内存的指针。经过使用这些指针,不一样进程就能够读或修改文件的内容,实现了对文件中数据的共享。

注意:文件映射是在多个进程间共享数据的很是有效方法,有较好的安全性。但文件映射只能用于本地机器的进程之间,不能用于网络中,而开发者还必须控制进程间的同步

2.     共享内存 

Win32API中共享内存(SharedMemory)实际就是文件映射的一种特殊状况。进程在建立文件映射对象时用0xFFFFFFFF来代替文件句柄(HANDLE),就表示了对应的文件映射对象是从操做系统页面文件访问内存,其它进程打开该文件映射对象就能够访问该内存块。

3.    匿名管道

匿名管道(Anonymous Pipe)在父进程和子进程之间,或同一父进程的两个子进程之间传输数据的无名字的单向管道。一般由父进程建立管道,而后由要通讯的子进程继承通道的读端点句柄或写端点句柄,而后实现通讯。父进程还能够创建两个或更多个继承匿名管道读和写句柄的子进程。这些子进程可使用管道直接通讯,不须要经过父进程。

4.    命名管道

FIFO,先进先出的通讯方式。

命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通讯的单向或双向管道。不一样于匿名管道的是命名管道能够在不相关的进程之间和不一样计算机之间使用,服务器创建命名管道时给它指定一个名字,任何进程均可以经过该名字打开管道的另外一端,根据给定的权限和服务器进程通讯。

5.    动态连接库

DLL解释:与动态连接库链接的可执行文件只包含它须要的函数的引用表,而不是全部的函数代码,只有在程序执行时, 那些须要的函数代码才被拷贝到内存中这样就使可执行文件比较小, 节省磁盘空间,操做系统使用虚拟内存,使得一份DLL驻留在内存中被多个程序使用,节省内存;

 Win32动态链接库(DLL)中的全局数据能够被调用DLL的全部进程共享,这就又给进程间通讯开辟了一条新的途径,固然访问时要注意同步问题。

6.    远程调用RPC

 Win32 API提供的远程过程调用(RPC)使应用程序可使用远程调用函数,这使在网络上用RPC进行进程通讯就像函数调用那样简单。RPC既能够在单机不一样进程间使用也能够在网络中使用。

7.    Socket

刚才咱们举例子简单说明了socket(套接字)的做用,咱们要知道目前socket是一种很是流行的网络通讯手段。

 WindowsSockets规范是以U.C.Berkeley大学BSD UNIX中流行的Socket接口为范例定义的一套Windows下的网络编程接口。除了Berkeley Socket原有的库函数之外,还扩展了一组针对Windows的函数,使程序员能够充分利用Windows的消息机制进行编程。

8.    剪贴板

Windows剪贴板应该算是一种比较简单开销小的IPC,内置在windows并使用系统的内部资源RAM,或者虚拟内存类临时保存剪切和复制的信息,系统预留的一块全局共享内存,用来暂存在各进程间进行交换的数据:提供数据的进程建立一个全局内存块,并将要传送的数据移到或复制到该内存块;接受数据的进程(也能够是提供数据的进程自己)获取此内存块的句柄,并完成对该内存块数据的读取。这里有一点疑问,我认为剪贴板并非把全部的信息复制到那个内存,而是把路径等信息存入再进行拷贝(这里但愿有大神给解释一下。。。)

9.    WM_COPYDATA消息

当一个应用向另外一个应用传送数据时,发送方只需使用调用SendMessage函数,参数是目的窗口的句柄、传递数据的起始地址、WM_COPYDATA消息。接收方只需像处理其它消息那样处理WM_COPY DATA消息,这样收发双方就实现了数据共享。WM_COPYDATA消息无疑是一种经济实惠的一中方法

 

Linux:

1.    管道:

与上述windows的管道相似,也分为匿名与有名字的管道。管道可用于具备亲缘关系进程间(父子,兄弟进程)的通讯,有名管道克服了管道没有名字的限制,容许不一样无亲缘关系的进程通讯。

2.    信号(signal):

信号是比较复杂的通讯方式,用于通知接受进程有某种事件发生,除了用于进程间通讯外,进程还能够发送信号给进程自己;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction

3.    报文(Message)队列(消息队列):

消息队列是消息的连接表,包括Posix消息队列system V消息队列。有足够权限的进程能够向队列中添加消息,被赋予读权限的进程则能够读走队列中的消息,注意消息队列是建立文件方式创建,因此即便添加消息的进程结束,保存在消息队列的消息也不会消失。

消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。

4.    共享内存:

上面描述了基本原理,每每与其它通讯机制,如信号量结合使用,来达到进程间的同步及互斥。

5.    信号量(semaphore):

主要做为进程间以及同一进程不一样线程之间的同步手段。(线程间通讯业常用信号量)

信号量是一个特殊的变量,只能对其进行初始化,PV以及删除操做(这里涉及到同步与锁的一些内容,能够查一下)。

6.    套接字(Socket):

上面描述过,可用于不一样机器之间的进程间通讯。

 

 

 

对几种IPC的简单比较

1.    管道,速度较慢,缓冲区大小受限,只能承载无格式的字节流。只能用于有亲缘关系的进程。

2.    FIFO管道,任何进程间均可以通讯,包括不一样机器上的管道,速度较慢。

3.    消息队列:由于位于内核中,因此容量受限,第一次读取时要注意上次添加的消息是否读取。

4.    信号量:不能传递复杂的消息,只用于同步信息。

5.    共享内存:能很容易的控制变量,速度快,要注意读写安全性,避免死锁等。

上面的每一种通讯机制都有很大的研究价值,若是你们想详细了解,还须要进一步去研究。
相关文章
相关标签/搜索