进程间的通讯方式有几种?有啥优缺点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程间的通讯方式有几种?有啥优缺点相关的知识,希望对你有一定的参考价值。

linux下进程间通信的几种主要手段简介:管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信; 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数); 报文(Message)队列(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。 套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。 参考技术A 用于进程间通讯(IPC)的四种不同技术:
1.消息传递(管道,FIFO,posix和system v消息队列)
2.同步(互斥锁,条件变量,读写锁,文件和记录锁,Posix和System V信号灯)
3.共享内存区(匿名共享内存区,有名Posix共享内存区,有名System V共享内存区)
4.过程调用(Solaris门,Sun RPC)
消息队列和过程调用往往单独使用,也就是说它们通常提供了自己的同步机制.相反,共享内存区通常需要由应用程序提供的某种同步形式才能正常工作.解决某个特定问题应使用哪种IPC不存在简单的判定,应该逐渐熟悉各种IPC形式提供的机制,然后根据特定应用的要求比较它们的特性.
必须考虑的四个前提:
1.联网的还是非联网的.IPC适用于单台主机上的进程或线程间的.如果应用程序有可能分布到多台主机上,那就要考虑使用套接字代替IPC,从而简化以后向联网的应用程序转移的工作.
2.可移植性.
3.性能,在具体的开发环境下运行测试程序,比较几种IPC的性能差异.
4.实时调度.如果需要这一特性,而且所用的系统也支持posix实时调度选项,那就考虑使用Posix的消息传递和同步函数.
各种IPC之间的一些主要差异:
1.管道和FIFO是字节流,没有消息边界.Posix消息和System V消息则有从发送者向接受者维护的记录边界(eg:TCP是没有记录边界的字节流,UDP则提供具有记录边界的消息).
2.当有一个消息放置到一个空队列中时,Posix消息队列可向一个进程发送一个信号,或者启动一个新的线程.System V则不提供类似的通知形式.
3.管道和FIFO的数据字节是先进先出的.Posix消息和System V消息具有由发送者赋予的优先级.从一个Posix消息队列读出时,首先返回的总是优先级最高的消息.从一个System V消息队列读出时,读出者可以要求想要的任意优先级的消息.
4.在众多的消息传递技术—管道,FIFO,Posix消息队列和System V消息队列—中,可从一个信号处理程序中调用的函数只有read和write(适用于管道和FIFO).
比较不同形式的消息传递时,我们感兴趣的有两种测量尺度:
1.带宽(bandwidth):数据通过IPC通道转移的速度.为测量该值,我们从一个进程向另一个进程发送大量数据(几百万字节).我们还给不同大小的I/O操作(例如管道和FIFO的write和read操作)测量该值,期待发现带宽随每个I/O操作的数据量的增长而增长的规律.
2.延迟(latency):一个小的IPC消息从一个进程到令一个进程再返回来所花的时间.我们测量的是只有一个1个字节的消息从一个进程到令一个进程再回来的时间(往返时间)
在现实世界中,带宽告诉我们大块数据通过一个IPC通道发送出去需花多长时间,然而IPC也用于传递小的控制信息,系统处理这些小消息所需的时间就由延迟提供.这两个数都很重要.本回答被提问者采纳

8.7 进程间的通讯:管道消息队列共享内存信号量信号Socket

进程间的通讯

进程间为什么需要通讯?

共享数据、数据传输、消息通知、进程控制

进程间的通讯有哪些类型?

首先,联系前面讲过的知识,进程之间的用户地址空间是相互独立的,不能进行互相访问,但是,内核空间却是共享的,所以进程间的通信要通过内核。

这里以Linux为例,介绍几种常见的Linux进程间的通讯方式:共享内存、管道、消息队列、信号量、信号。

管道

如果你学习过linux命令肯定见过 | 这个竖线。

$ ps auxf | grep mysql

上面命令里的竖线 | 就是一个管道,它在这里的作用是:把前一个命令(ps auxf)的输出,作为后一个命令(grep mysql)的输入。

由此可见,管道传输数据是单向的。如果想互相通信,我们最少需要两个管道。

上面这例子的管道是没有名字的,所以我们称 | 这样的管道为匿名管道,用完即毁。

还有一种管道是命名管道,也叫做FIFO,先进先出的意思。

在使用命名管道前,需要通过mkfifo命令创建,还要加上管道的名字。

$ mkfifo myPipe

管道名字就是myPipe,在Linux中也是以文件的形式存在的:

w-rw-r--. 1 iron2222 iron2222    0 Dec  4 22:20 myPipe

我们尝试向这个管道里写入数据:

$ echo "hello" > myPipe //把数据写进去
                        //你会发现停住了,没反应

因为只有管道之中的数据被读完后,命令才可以正常退出:

$ cat < myPipe 
hello

注意,一定要在另一个终端上,输入该命令,保持原终端界面保持不变,这样执行该命令后会很明显的看到,原终端命令可以正常退出了。

从这里可以看出来,管道这种方式:效率低,不适合频繁的交换数据

消息队列

消息队列的通讯模式:A进程给B进程发消息,A进程把消息放到对应的消息队列之后就可以直接返回了,B进程需要的时候去读就可以了。

消息队列的本质是,保存在内核中的消息链表。发送方与接收方要约定好,消息体的数据类型与大小。读完之后,内核就会把这个消息体删除。

不好的地方:消息队列在通讯的过程中,存在用户态与内核态之间的数据拷贝开销。

共享内存

共享内存的机制,就是拿出来一块虚拟地址空间,映射到相同的物理内存中。读取效率很高。

缺点是,如果两个进程同时向一块物理地址中写数据时,会造成覆盖。

信号量

为了防止出现共享内存那样,出现多进程竞争共享资源,所以需要保护机制,让共享的资源,在任意时刻只能被一个进程访问。

信号量其实就是一个整型计数器,主要用于实现进咸亨间的互斥和同步,而不是用于缓存进程间通信的数据。

初始为1,有A进程去用就变成0,若此时有B进程想用,就变-1,使B进程阻塞。

就相当于一种标记,告诉进程这个共享资源有没有空。

信号

信号,一般用于那些处于异常情况下的进程间的通信,是一种异步信号,就是一个数字。

比如,在Linux中,为了相应不同的事件,提供了几十种信号,反别代表不同的意义:

$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

举一个大家常见的例子:

在shell终端里,我们可以使用某些快捷键,给进程发信号

  • Ctrl+C 会产生SIGINT信号,终止进程;
  • Ctrl+Z 会产生SIGTSTP信号,表示停止进程,但进程未结束。

也可以通过kill命令,但前提要知道进程的PID号。

  • kill -9 1050,表示给PID为1050的进程发送9) SIGKILL信号,立即结束该进程。

唯一的异步通信机制,进程需要为信号设置相应的监听处理,执行相关操作。

Socket

如果你想跨网络与不同主机上的进程进行通讯,就要用到Socket了。

各个通讯方式总结对比

以上是关于进程间的通讯方式有几种?有啥优缺点的主要内容,如果未能解决你的问题,请参考以下文章

IPC(进程间的通讯方式)

Multithread 什么时候处理多线程,有几种方式,优缺点?

12、注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意。

应用程序之间互相通讯的几种方法

进程通信+线程同步

Spring框架有几种配置方式?它们在技术上有何区别? (不是优点或缺点..)