操做系统核心原理-3.进程原理(下):进程通讯

  进程做为人类的发明,天然也免不了脱离人类的习性,也有通讯的需求。若是进程之间不进行任何通讯,那么进程所能完成的任务就要大打折扣。人类的通讯方式无外乎对白(经过声音沟通)、打手势、写信、发电报、拥抱等方法。同理,进程也能够经过一样的方式来进行通讯。本篇咱们就来看看进程的这些交互方式。安全

1、进程对白:管道、套接字

  人们最经常使用的通讯手段就是对白,一方发出声音,另外一方接收声音。而声音的传递须要经过一些介质,例如:空气(face to face)、线缆(有线电话)等。相似的,进程对白就是一个进程发出某种数据信息,另一方接收数据信息,而这些数据信息经过一片共享的存储空间进行传递。服务器

1.1 管道

  一个进程向存储空间的一端写入信息,另外一个进程存储空间的另一端读取信息,这个就是管道。就像两我的对白的媒介是空气也能够是线缆同样,管道所占的空间既能够是内存也能够是磁盘。网络

  要建立一个管道,一个进程只须要调用管道建立的系统调用便可,该系统调用所作的事情就是在某种存储介质上划出一片空间,赋给其中一个进程写的权利,另外一个进程读的权利便可。数据结构

  例如在Linux下,咱们经过Shell命令输入两个命令,中间经过符号“|”来建立两个命令之间的管道:socket

$ sort < file1 | grep zou

  上面一个命令表示:对file1的内容首先进行排序,排序完成后的结果将做为grep的输入,在结果里面找出全部包括字符串zou的文本行。也就是说,在两个任务“排序“(sort)和”查找”(grep)之间建立了一个管道,数据从sort流向了grep。spa

1.2 套接字

socket

  套接字(Socket)的功能很是强大,能够支持不一样层面、不一样应用、跨网络的通讯。使用套接字进行通讯须要双方均建立一个套接字,其中一方做为服务器方,另一方做为客户方。服务器方必须首先建立一个服务区套接字,而后在该套接字上进行监听,等待远方的链接请求。客户方也要建立一个套接字,而后向服务器方发送链接请求。服务器套接字在受到链接请求以后,将在服务器方机器上新建一个客户套接字,与远方的客户方套接字造成点到点的通讯通道。以后,客户方和服务器方即可以直接经过相似于send和recv的命令在这个建立的套接字管道上进行交流了。操作系统

  例如,在C#中咱们能够轻松地建立一个服务器方的Socket:3d

    // 建立Socket->绑定IP与端口->设置监听队列的长度->开启监听链接
    socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socketWatch.Bind(new IPEndPoint(IPAddress.Parse(txtIPAddress.Text), int.Parse(txtPort.Text)));
    socketWatch.Listen(10);

1.3 不足之处

  (1)必须首先在通讯的进程间创建链接(管道或套接字),这须要消耗系统资源;code

  (2)通讯是自愿的,而管道和套接字须要强制双方进行通讯;对象

  (3)因为创建链接须要消耗时间,一旦创建就应该尽量多的通讯,若是通讯信息量很小,则就是“杀鸡用牛刀”了;

2、进程电报与旗语:信号与信号量

2.1 电报:信号

  信号相似于咱们生活中的电报,若是你想给某人发一封电报,就拟好电文,而后将报文和收报人的信息都交给电报公司。电报公司则将电报发送到收报人所在地的邮局,并通知收报人来取电报。其中,发报文时无需收报人实现知道,也无需进行任何协调。若是对方选择不对信号作出响应,则将被OS终止运行。

  在计算机中,信号就是一个内核对象或者是一个内核数据结构。发送方将该数据结构的内容填好,并指明该信号的目标进程后,发出特定的软件中断(这就是一个发电报的操做)。OS接收到特定的中断请求后,知道是有进程要发送信号,因而到特定的内核数据结构里查找信号接收方,并进行通知。接到通知的进程则对信号进行相应处理。

2.2 旗语:信号量

  信号量来源于铁路的运行:在一条单轨铁路上,任什么时候候只容许有一列火车行驶在该铁路上,而管理这条铁路的系统就是信号量。任何一列火车必须等到代表该铁路能够行驶的信号后才能进入轨道。当列车进入后,须要将信号改成禁止状态进入来防止别的列车同时进入。而当列车驶出单轨后,则须要将信号变回容许进入状态,这很像之前的旗语。固然,经过联想到咱们实际开发中常常用的锁,这就更容易理解了。

  在计算机中,信号量实际上就是一个简单整数。一个进程在信号变为0或1的状况下推动,并将信号变为1或0来防止别的进程同时推动。当该进程完成任务后,则将信号再改成0或1,从而容许其余进程执行。从而咱们也能够看出,信号量已经不仅是一种通讯机制,更是一种同步机制

3、进程拥抱:共享内存

  前面经过对话、发电报、旗语已经知足了多种通讯须要,可是当两个进程要共享大量数据时就无法十分知足需求。就如同两个坠入爱河的骚年,它们互相喜欢并想要在一块儿同居(共享大量数据),这时打电话、发电报、握手对话就显得不够了。这时候,它们须要的就是拥抱,只有牢牢拥抱才能尽量地共享,feeling so good!

3.1 共享内存

  进程的拥抱就是共享内存,两个进程共同拥有同一片内存。对于这片内存中的任何内容,两者都可以访问。要使用共享内存进行通讯,进程A首先须要建立一片内存空间做为通讯用,而其余进程B则将片内存映射到本身的(虚拟)地址空间。这样,进程A读写本身地址空间中对应共享内存的区域时,就是在和进程B进行通讯。

3.2 不足之处

  (1)使用共享内存机制通讯的两个进程必须在同一台物理机上;

  (2)安全性脆弱,假如一个进程有病毒,会很容易传给另一个进程;

4、信件发送:消息队列

  消息队列是一列具备头和尾的消息排列,新来的消息放在队列尾部,而读取消息则从队列头部开始,以下图所示:

  这样看来,它和管道十分相似,一头读,一头写?的确,看起来很像管道,但又不是管道:

  (1)消息队列无固定的读写进程,任何进程均可以读写;而管道须要指定谁读和谁写;

  (2)消息队列能够同时支持多个进程,多个进程能够读写消息队列;即所谓的多对多,而管道是点对点;

  (3)消息队列只在内存中实现,而管道还能够在磁盘上实现;

参考资料

邹恒明,《操做系统之哲学原理》,机械工业出版社

 

相关文章
相关标签/搜索