进程之间有哪些通信⽅式?如何通信?
进程之间有哪些通信⽅式?如何通信?
1. 管道
我们先来看⼀条linux语句
netstat -antlp | grep 8080
学过 Linux 命名的估计都懂这条语句的含义,其中 " | " 是管道的意思,它的作⽤就是把前⼀条命令的输出作为后⼀条命令的输⼊。在这⾥就是把 netstat -antlp 的输出结果作为grep 8080 这条命令的输⼊
如果两个进程要进⾏通信的话,就可以⽤这种管道来进⾏通信了,并且我们可以知道这条竖线是没有名字的,所以我们把这种通信⽅式称之为匿名管道
并且这种通信⽅式是单向的,只能把第⼀个命令的输出作为第⼆个命令的输⼊,如果进程之间想要互相通信的话,那么需要创建两个管道
既然有匿名管道,那也意味着有命名管道,下⾯我们来创建⼀个命名管道
mkfifo test
这条命令创建了⼀个名字为 test 的命名管道
接下来我们⽤⼀个进程向这个管道⾥⾯写数据,然后有另外⼀个进程把⾥⾯的数据读出来
echo "this is a pipe" > test ## 写数据
这个时候管道的内容没有被读出的话,那么这个命令就会⼀直停在这⾥,只有当另外⼀个进程把 test ⾥⾯的内容读出来的时候这条命令才会结束。接下来我们⽤另外⼀个进程来读取cat < test ## 读数据
我们可以看到,test ⾥⾯的数据被读取出来了,上⼀条命令也执⾏结束了
从上⾯的例⼦可以看出,管道的通知机制类似于缓存,就像⼀个进程把数据放在某个缓存区域,然后等着另外⼀个进程去拿,并且是管道是单向传输的。
这种通信⽅式有什么缺点呢?显然,这种通信⽅式效率低下,你看,a 进程给 b 进程传输数据,只能等待 b 进程取了数据之后 a 进程才能返回。
所以管道不适合频繁通信的进程。当然,他也有它的优点,例如⽐较简单,能够保证我们的数据已经真的被其他进程拿⾛了。我们平时⽤ Linux 的时候,也算是经常⽤
2. 消息队列
那我们能不能把进程的数据放在某个内存之后就马上让进程返回呢?⽆需等待其他进程来取就返回呢?
答是可以的,我们可以⽤消息队列的通信模式来解决这个问题,例如 a 进程要给 b 进程发送消息,只需要把消息放在对应的消息队列⾥就⾏了,b 进程需要的时候再去对应的
消息队列⾥取出来。同理,b 进程要个 a 进程发送消息也是⼀样,这种通信⽅式也类似于缓存吧
这种通信⽅式有缺点吗?答是有的,如果 a 进程发送的数据占的内存⽐较⼤,并且两个进程之间的通信特别频繁的话,消息队列模型就不⼤适合了。因为 a 发送的数据很⼤的话,意味发送消息(拷贝)这个过程需要花很多时间来读内存。
进程间通信效率最高的方式是哪有没有什么解决⽅案呢?答是有的,请继续往下看
3、共享内存
共享内存这个通信⽅式就可以很好着解决拷贝所消耗的时间了
但是⼀般来说每个进程不是有⾃⼰的独⽴内存吗?两个进程怎么就可以共享⼀块内存了?
我们都知道,系统加载⼀个进程的时候,分配给进程的内存并不是实际物理内存,⽽是虚拟内存空间,那么我们可以让两个进程各⾃拿出⼀块虚拟地址空间来,然后映射到相同的物理内存中,这样,两个进程虽然有着独⽴的虚拟内存空间,但有⼀部分却是映射到相同的物理内存,这就完成了内存共享机制了
4、信号量
共享内存最⼤的问题是什么?没错,就是多进程竞争内存的问题,就像类似于我们平时说的线程安全问题,如何解决这个问题?这个时候我们的信号量就上场了
信号量的本质就是⼀个计数器,⽤来实现进程之间的互斥与同步,例如信号量的初始值是 1,然后 a 进程来访问内存1的时候,我们就把信号量的值设为 0,然后进程b 也要来访问内存1的时候,看到信号量的值为 0 就知道已经有进程在访问内存1了,这个时候进程 b 就会访问不了内存1,所以说,信号量也是进程之间的⼀种通信⽅式
5、Socket
上⾯我们说的共享内存、管道、信号量、消息队列,他们都是多个进程在⼀台主机之间的通信,那两个相隔⼏千⾥的进程能够进⾏通信吗?
答是必须的,这个时候 Socket 这家伙就派上⽤场了,例如我们平时通过浏览器发起⼀个 http 请求,然
后服务器给你返回对应的数据,这种就是采⽤ Socket 的通信⽅式了。
总结
所以,进程之间的通信⽅式有:
1、管道
2、消息队列
3、共享内存
4、信号量
5、Socket
1.管道:速度慢,容量有限,只有⽗⼦进程能通讯
2.FIFO:任何进程间都能通讯,但速度慢
3.消息队列:容量受到系统限制,且要注意第⼀次读的时候,要考虑上⼀次没有读完数据的问题
4.信号量:不能传递复杂消息,只能⽤来同步
5.共享内存区:能够很容易控制容量,速度快,但要保持同步,⽐如⼀个进程在写的时候,另⼀个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以⽤作线程间通讯,不过没这个必要,线程间本来就已经共享了同⼀进程内的⼀块内存
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论