浅析Linux进程通信的几种方式及其比较:进程间通信有哪些方式

时间:2019-08-19 05:06:08 来源:QQ空间素材网 本文已影响 QQ空间素材网

  摘要:本文通过对Linux下几种主要通信方式进行概述,并结合Linux系统的系统调用对OS中的实现进行简要概述,并对其优缺点进行分析,阐述了在不同通信情况下应该选择何种通信方式进行选择。
  关键词:Linux;通讯方式
  中图分类号:TP39 文献标识码:A
  1.进程通信的基本概念
  进程间通信(IPC)指的是至少两个进程间传送数据或者信号的一些技术和方法,进程是计算机系统分配资源的基本单位,每个进程都有自己的一部分独立的系统资源,彼此是隔离的。为了能使不同的进程互相访问资源并进行协调工作,才有了进程之间的通信。
  2.进程通信的分类
  操作系统中进程间传递的信息量有多有少,因此根据进程通信时信息量大小的不同,可以将进程通信划分为两大类型,一种类型主要用于传递进程之间同步、互斥、终止、挂起等控制信息的传递,由于进程互斥与同步交换的信息量较少,并且每次通信传递的信息量固定且效率较低,因此称这两种通信方式为低级通信方式,主要方式有信号量。另一种类型在进程间以较高的效率传送大量数据,被称为高级通信方式,主要方式有管道,共享内存和消息队列。下面对这四种通信方式进行简单的论述。
  3.信号量
  信号量也叫信号灯,是一个确定的二元组(S,Q),其中S是个具有非负初置的整形变量,表示的是临界资源的实体。信号量的值有以下两种情况:
  1)代表可用资源的数量,此时Q 的队列为空。
  2)代表由于等待此种资源而被阻塞的进程的数量,也就是Q队列中进程的个数。
  信号量的值仅能由P、V操作进行改变,其中p操作和v操作是不可中断的程序段,称为原语操作,它是典型的同步机制之一。每执行一次P操作表示分配一个该类资源给执行P操作的进程,因此P操作将信号量的值减1,当信号量的值小于0时,表示已经没有这类资源可供分配了,所以请求资源的进程将被阻塞而被插入到Q的等待队列当中。此时,信号量的绝对值等于Q队列中进程的个数,即等待分配该类资源的进程数。执行一次V操作意味着进程释放出一个该类可用资源,因而V操作是将信号量的值加1。因信号量的值小于等于0表示在该信号量的等待队列中有请求该类型而被阻塞的进程,因而应把该信号量等待队中的队首的进程唤醒,即进程的状态由阻塞状态变为活动就绪状态。
  信号量的创建:Linux系统中使用semget(key,nSemes,flag)来创建一个信号量,key是标识信号量的关键字,nSemes表示创建信号量的个数,flag表示为信号量存取权标志与建立标志。
  信号量的操作:Linux系统中采用semop(semid,sops,nsops)来实现对信号量的操作,semid为关键字值,由semget返回得来,第二个参数是指向将要操作的数组的指针,nsops为数组sops的大小。
  4.管道通信方式
  管道是Linux支持的最初Unix IPC形式之一,当两个进程利用管道进行通信时,发送信息的进程称为写进程,接收信息的进程称为读进程。管道通信方式的中间介质就是文件,通常称这种文件为管道文件.它就像管道一样将一个写进程和一个读进程连接在一起,实现两个进程之间的通信。写进程通过写入端(发送端)往管道文件中写入信息,读进程通过读出端(接收端)从管道文件中读取信息。管道具有如下特点:
  1)管道是半双工的,数据只能向一个方向流动,数据只能由写的一方向读得一方流动。
  2)单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,成为管道文件,但它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。
  3)数据的读出和写入:管道建立时,通信两端的任务都是被固定了的,也就是说,一端只能用于读,而另一端只能用于写,写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
  5.消息队列
  消息队列的基本思想是:系统管理一组消息缓冲区,并称之为消息缓冲池,其中每个消息缓冲区存放一条消息。消息实际上就是一组信息。当一个进程要发送消息时,首先向系统申请一个消息缓冲区,写入消息后将其连接到接受进程PCB所指示的消息队列。接受进程在适当的时候从其消息队列中取得消息,并立即释放该消息缓冲区,交回给系统管理。
  消息队列就是一个消息的链表。就是把消息看作一个记录,并且这个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读出消息。
  Linux采用消息队列的方式来实现消息传递。这种消息的发送方式是:发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待。这种通信机制相对简单,但是应用程序使用起来就需要使用相对复杂的方式来应付了。新的消息总是放在队列的末尾,接收的时候并不总是从头来接收,可以从中间来接收。
  Linux中定义了一个名为msgbuf的数据结构来表示消息,并利用MSGGET()来创建一个消息队列,然后返回这个消息队列的标识号,然后调用MSGSND()向一个消息队列发送一个消息,接收进城通过MSGRCV()来从一个消息队列中收到一个消息。在通信双方进行通信的过程中,系统可以利用MSGCTL()在消息队列上执行指定的操作,更具参数的不同和权限的不同,可以执行检索、删除等得操作。
  共享的消息队列是一个临界资源,针对同一消息队列的诸发送和接收进程必须保证互斥进入,这种进程间的同步和互斥是由系统提供的系统调用自动实现的,所以用户在使用时不需要再考虑它们之间的同步关系,非常方便。
  6.共享内存
  除上述几种通信方式之外,Linux还提供了正文段,也就是程序段的共享,当若干进程需要对公共数据区中的数据进行频繁操作时,共享内存的通信方式是一种很有用的通信机制,而且是以一种效率较高的进程通信机制。其基本思想是:系统管理一组共享内存控制块,当用户程序进程需要使用共享内存段时,使用SHMGET()系统调用申请一个共享内存段,系统位置分配存储空间和建立有关的数据结构,并返回该共享内存段的标识符shmid,然后系统调用SHMAT()将由标识符shmid标识的共享内存段附加到进程地址空间,一旦将一个共享内存段连接到进程逻辑地址空间后,进程可以像访问其私有数据段一样存取该共享内存段中的数据。当不在使用共享内存时,由系统调用SHMDT()将由参数定位的共享内存段脱离调用进程的数据段。在此期间,可以使用系统调用SHMCTL()查询由shmid标识的共享内存段的状态和设置有关参数,对共享内存段进行控制。
  共享内存通信与消息缓冲通信有很多类似之处:都是使用一个id来标识一个IPC目标,通过使用GET(msgget,shmget)来建立一个IPC目标,都要进行权限检查等来实现通信。不同点是:共享内存一旦附接后就作为进程地址空间的一部分提供给进程使用对于该共享内存的读写操作如同对进程私有的缓冲区一样。操作系统不再关心进程间是如何使用这个共享内存,更无法进行干预。
  7.各种通信方式的比较和优缺点。
  如果用户传递的信息较少。或是需要通过信号来触发某些行为,信号量不失为一种简捷有效的进程间通信方式。但若是进程间要求传递的信息量比较大或者进程间存在交换数据的要求,就需要考虑高级通信机制。无名管道简单方便。但局限于单向通信的工作方式,并且只能在创建它的进程及其子孙进程之间实现管道的共享。有名管道虽然可以提供给任意关系的进程使用,但是由于其长期存在于系统之中,使用不当容易出错.所以普通用户一般不建议使用。
  消息缓冲可以不再局限于父子进程,而允许任意进程通过共享消息队列来实现进程间通信,并由系统调用函数来实现消息发送

网站地图 | 关于我们 | 联系我们 | 广告服务 | 免责声明 | 在线留言 | 友情链接 | RSS 订阅 | 热门搜索
版权所有 QQ空间素材网 www.qzoneai.com