进程间通信的方式有哪几种?
扫描二维码
随时随地手机看文章
进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。另外,系统空间是“公共场所”,各进程均可以访问,所以内核也可以提供这样的条件。此外,还有双方都可以访问的外设。在这个意义上,两个进程当然也可以通过磁盘上的普通文件交换信息,或者通过“注册表”或其它数据库中的某些表项和记录交换信息。广义上这也是进程间通信的手段,但是一般都不把这算作“进程间通信”。
进程间通信(IPC,Interprocess communication)是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息。这使得一个程序能够在同一时间里处理许多用户的要求。因为即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的运行,进程之间必须互相通话。IPC接口就提供了这种可能性。每个IPC方法均有它自己的优点和局限性,一般,对于单个程序而言使用所有的IPC方法是不常见的。IPC方法包括管道(PIPE)、消息排队、旗语、共用内存以及套接字(Socket)。
进程间通信的6种方式
1、管道:
1)管道传输数据是单向的,如果想相互通信,需要建立两个管道。
2)管道这种通信方式效率低, 不适合进程间频繁地交换数据。
3)优点是简单,很容易得知管道里的数据已经被另一个进程读取了。
2、消息队列:
1)消息队列是保存在内核中的消息链表,AB进程互相发送消息,只要把数据放在消息队列即可,之后进程遍可以正常返回,另一个进程会从消息队列中读取数据。
2)缺点:消息队列通信过程中,存在用户态与内核态之间的数据拷贝开销。
3、共享内存:
1)操作系统对于内存管理,采用的是虚拟内存技术,也就是每个进程都有自己独立的虚拟内存空间,不同进程的虚拟内存映射到不同的物理内存中。所以,即使进程A和 进程B的虚拟地址是一样的,其实访问的是不同的物理内存地址,对于数据的增删查改互不影响。
2)共享内存的机制,就是拿出一块虚拟地址空间来,映射到相同的物理内存中。这样这个进程写入的东西,另外一个进程马上就能看到了,都不需要拷贝来拷贝去,传来传去, 大大提高了进程间通信的速度。
3)缺点:当多个进程向同一个共享内存中写入数据时可能会产生覆盖(如在工作中,当多人同时修改一份共享文档时别人可能会将你添加的内容修改删除或覆盖),如果只读则没有任何问题。
4、信号量:
1)为了防止多进程竞争共享资源,而造成的数据错乱,所以需要保护机制,使得共享的资源,在任意时刻只能被一个进程访问。正好,信号量就实现了这一保护机制。
2)信号量其实是一个整型的计数器,主要用于实现进程间的互斥与同步。
3)信号量表示资源的数量,控制信号量的方式有两种原子操作:
一个是P操作,这个操作会把信号量减去1,相减后如果信号量<0,则表明资源已被占用,进程需阻塞等待;相减后如果信号量>=0,则表明还有资源可使用,进程可正常继续执行。
另一个是V操作,这个操作会把信号量加上1,相加后如果信号量<=0,则表明当前有阻塞中的进程,于是会将该进程唤醒运行;相加后如果信号量>0,则表明当前没有阻塞中的进程。
举例说明:
A:如果要使得两个进程互斥访问共享内存,我们可以初始化信号量为1。
具体的过程如下:
进程A在访问共享内存前,先执行了P操作,由于信号量的初始值为1,故在进程A执行P操作后信号量变为0,表示共享资源可用,于是进程A就可以访问共享内存。
若此时,进程B也想访问共享内存,执行了P操作,结果信号量变为了-1,这就意味着临界资源已被占用ェ因此进程B被阻塞。
直到进程A访问完共享内存,才会执行V操作,使得信号量恢复为0,接着就会唤醒阻塞中的进程B,使得进程B可以访问共享内存,最后完成共享内存的访问后,执行 V操作,使信号量恢复到初始值1。
可以发现,信号初始化为1,就代表着是互斥信号量,它可以保证共享内存在任何时刻只有一个进程在访问,这就很好的保护了共享内存。
B:用信号量来实现多进程同步的方式,我们可以初始化信号量为0。
具体过程如下:
如果进程B比进程A先执行了,那么执行到P操作时,由于信号量初始值为0,故信号量会变为-1,表示进程 A 还没生产数据,于是进程B就阻塞等待。
当进程A生产完数据后,执行了V操作,就会使得信号量变为0,于是就会唤醒阻塞在P操作的进程B。
进程B被唤醒后,意味着进程A已经生产了数据,于是进程B就可以正常读取数据了。
可以发现,信号初始化为0,就代表着是同步信号量,它可以保证进程A应在进程B之前执行。
5、信号:
1)信号一般用于一些异常情况下的进程间通信,是一种异步通信,它的数据结构一般就是一个数字。
2)信号是进程间通信机制中唯一的异步通信机制。
3)进程需要为信号设置相应的监听处理,当收到特定信号时,执行相应的操作,类似很多编程语言里的通知机制。
6、套接字:
1)前面提到的管道、消息队列、共享内存、信号量和信号都是在同一台主机上进行进程间通信,那要想跨网络与不同主机上的进程之间通信,就需要Socket通信了。
2)Socket通信不仅可以跨网络与不同主机的进程间通信,还可以在同主机上进程间通信。
系统IPC的三种方式类同,都是使用了内核里的标识符来识别.FAQ1: 管道与文件描述符,文件指针的关系?答: 其实管道的使用方法与文件类似,都能使用read,write,open等普通IO函数. 管道描述符来类似于文件描述符. 事实上, 管道使用的描述符,文件指针和文件描述符最终都会转化成系统中SOCKET描述符. 都受到系统内核中SOCKET描述符的限制. 本质上LINUX内核源码中管道是通过空文件来实现.FAQ2: 管道的使用方法?答: 主要有下面几种方法: 1)pipe, 创建一个管道,返回2个管道描述符.通常用于父子进程之间通讯. 2)popen, pclose: 这种方式只返回一个管道描述符,常用于通信另一方是stdin or stdout; 3)mkpipe:命名管道, 在许多进程之间进行交互.FAQ3: 管道与系统IPC之间的优劣比较?答: 管道: 优点是所有的UNIX实现都支持, 并且在最后一个访问管道的进程终止后,管道就被完全删除;缺陷是管道只允许单向传输或者用于父子进程之间.系统IPC: 优点是功能强大,能在毫不相关进程之间进行通讯; 缺陷是关键字KEY_T使用了内核标识,占用了内核资源,而且只能被显式删除,而且不能使用SOCKET的一些机制,例如select,epoll等.FAQ4: WINDOS进程间通信与LINUX进程间通信的关系?答: 事实上,WINDOS的进程通信大部分移植于UNIX, WINDOS的剪贴板,文件映射等都可从UNIX进程通信的共享存储中找到影子.FAQ5: 进程间通信与线程间通信之间的关系?答: 因为WINDOWS运行的实体是线程, 狭义上的进程间通信其实是指分属于不同进程的线程之间的通讯.而单个进程之间的线程同步问题可归并为一种特殊的进程通信.它要用到内核支持的系统调用来保持线程之间同步. 通常用到的一些线程同步方法包括:Event, Mutex,信号量Semaphore,临界区资源等.
IPC目的 播报1)数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间。2)共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。3)通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。4)资源共享:多个进程之间共享同样的资源。为了做到这一点,需要内核提供锁和同步机制。5)进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。进程通过与内核及其它进程之间的互相通信来协调它们的行为。Linux支持多种进程间通信(IPC)机制,信号和管道是其中的两种。除此之外,Linux还支持System V 的IPC机制(用首次出现的Unix版本命名)。