进程间的4种通信方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/May_3/article/details/80005638

写在前面:

    这篇博客主要将会介绍进程间的4种主要通信方式。在介绍进程间如何通信之前,我们先来看看进程和线程的概念。了解进程和线程的区别。

参考博客:https://blog.csdn.net/whl_program/article/details/70217354

-------------------------------------------------------------------------------

    进程和线程:

   进程:一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。

    线程:是在进程中执行的一个任务单元。

    (1)进程单独占有一定的内存地址空间,所以进程间存在内存隔离,数据时分开的,数据共享复杂但是同步简单,各个进程之间互不干扰;而线程共享所属进程占有的内存地址空间和资源,数据共享简单,但是同步复杂。 
    (2)进程单独占有一定的内存地址空间,一个进程出现问题不会影响其他进程,不影响主程序的稳定性,可靠性高;一个线程崩溃可能影响整个程序的稳定性,可靠性较低。 

   (3)进程单独占有一定的内存地址空间,进程的创建和销毁不仅需要保存寄存器和栈信息,还需要资源的分配回收以及页调度,开销较大;线程只需要保存寄存器和栈信息,开销较小。

   (4)进程是操作系统进行资源分配的基本单位(进程之间互不干扰),而线程是操作系统进行调度的基本单位(线程间互相切换)。

-------------------------------------------------------------------------------

    进程间的通信方式:

    进程通信,InterProcess Communication,简称为IPC,是指不同的进程之间相互交换信息。进程间的通信方式有很多种,如:管道、信号、共享内存、消息队列、套接字、信号量等,博客中,将会重点描述管道、信号、共享内存、消息队列。

    (1)管道

    管道的实质是一个内核缓冲区,进程以先进先出的方式从缓冲区存取数据,管道一端的进行顺序的将进程数据写入缓冲区,另一端的进则顺序地读取数据,该缓冲区可以看做一个循环队列,读和写的位置都是自动增加的,一个数据只能被读一次,读出以后在缓冲区就不复存在了。当缓冲区读空或者写满时,有一定的规则控制相应的读进程或写进程是否进入等待队列,当空的缓冲区有新数据写入或满的缓冲区有数据读出时,就唤醒等待队列中的进程继续读写。

  •     管道是一种半双工通信方式,数据只能单向流动。需要进行通信时,需要建立2个管道。
  •     无名管道主要应用于具有亲缘关系的进程之间通信,所谓亲缘关系,指父子进程。
  •     单独构成一个独立的文件系统,管道对于管道两道的进程而言,就是一个文件,但它不是一个普通的文件,不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。 

    管道分为无名管道(FIFO)和有名管道(PIPE),除了建立,打开,删除的方式不同Wait,这两种管道几乎是一样的。都是通过内核缓冲区实现数据传输。

  •     无名管道:主要用于相关进程之间的通信,例如父子进程,通过系统调用来创建并打开,当最后一个使用它的进程关闭对他的引用时,无名管道将自动撤销。
  •     有名管道:在磁盘上有对应的节点,但没有数据块。也就是说,只是拥有一个名字和相应的访问权限,通过mknode()系统调用或者mdfifo函数来建立。一旦建立,任何检查都可以通过文件名将其打开和进行读写,而不局限于父子进程。注意:前提是进程对FIFO有访问权限。当不再被进程使用时,FIFO在内存中释放,但磁盘节点仍然存在。

    (2)信号

    信号是LInux系统中,用于进程之间通信或操作的一种机制。信号可以再任何时候发送给某一进程,而无须知道该进程的状态。如果该进行未处于执行状态,则该信号会由内核保存起来,直到该进程恢复运行并传递给他为止。如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞状态被取消时,才被传递给进程。

    在一个信号的生命周期中,有2个阶段:生成和传送。第一个阶段:当一个事件发生时,需要通知一个进程,这时生成一个信号。当进程识别出信号的到来,就采取适当的动作来传送或处理信号。在信号到来和进程对信号进行处理之间,信号在进程上挂起(pending)。

    (3)共享内存

    共享内存允许两个或者多个进程共享一个给定的存储器,这一段存储器可以被两个或两个以上的进程映射到自身的地址空间中,一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取或读出,从而实现了进程间的通信。

    采用共享内存进行通信的一个主要好处是效率高,因为进程可以直接读写内存,不需要任何数据的拷贝,对于管道和消息队列等通信方式,则需要在内核和用户控件进行四次的数据拷贝,而共享内存则只拷贝两次:一次是从输入文件到共享内存,另一次是从共享内存到输出文件中。

    共享内存的实现方式有两种:内存映射、共享内存机制。

    (4)消息队列    

    消息队列,就是一个消息的链表,是一系列保存在内核中消息的列表,用户进程可以向消息队列添加消息,也可以向消息队列读取消息。

    消息队列与管道通信相比,其优势是对每个下次指定特定的消息类型,接收的时候不需要按照队列此项,而是可以根据自定义条件接收特定类型的消息。

    可以把消息看做是一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息,对消息队列有读权限的进程可以从消息队列中读取消息。




    

猜你喜欢

转载自blog.csdn.net/May_3/article/details/80005638