这里有我了解的一些进程间通信的方式
1 . 管道
-
匿名管道
-
这种通信方式是单向的, 只能把第一个管道输出传递给目标管道
-
匿名管道虽然实现类进程间的通信, 但是单单方向的通信肯定是无法满足我们对进程间通信的需求的, 那么你可以使用
命名管道
来进行进程间的相互通信netstat -tulnp | grep 8027
-
-
命名管道
- 如上所述, 命名管道可以实现进程间双向通信
- 命名管道可以实现进程间双向通信
mkfifo test // 创建命名管道 echo "this is a nnew pipe" > test // 写数据 cat < test // 读数据
- 以上命令可以实现了一个进程写入数据, 然后另一个进程读取数据, 从而实现进程间通信, 当然也可以这个进程写入数据, 然后等待另一个进程来读取数据, 从而实现了进程间的双向通信
- 管道的通知机制和
缓存
的运行机制十分相似, 就如一个进程将数据放入管道区域, 然后等另一个进程读取, 当然管道也是单向传输
,我们通过它们的名字可以实现双向数据传输 - 明白了这么多, 那么它的缺点也就很明显了, 没错, 就是
效率十分低下
, 只有当进程放入管道的数据被读取后才能返回, 只要进程间通信量一多, 那么不崩溃都是神奇的, 那么又该怎么做呢, 这时候就可以将目光转向消息对列
了
2 . 消息对列
- 如何解决命名管道效率低下的问题呢, 消息队列是如何运行的呢?
- 消息队列的通信模式就是用来解决这个问题的, 如果 进程1 要给 进程2 发送消息, 只需要把消息放在对应的消息对伦理中就可以了, 进程2 需要的时候再去对应的消息对列里面将数据取出
- 这样就解决了一定程度上的进程间通信数据量的问题, 那么你就想问, 消息对立是否有无缺点, 缺点又是咋样的呢 ?
- 当然没有完美无缺的技术
- 你可以想象一下, 如果 进程1 发送的数据占用的内存比较大, 并且这两个进程间通信比较频繁的话, 消息队列模型就有心无力了, 因为 进程1 发送的数据很大, 意味着
发送消息(拷贝)
该过程需要花费很多的时间 - 那么你肯定又想知道该如何解决这个问题了, 别急, 往下看
3 . 共享内存
共享内存
这个通信方式就可以很好解决拷贝所消耗的时间了- 我们都知道, 系统加载一个进程的时候, 分配给进程的内存并不是
实际物理内存
, 而是虚拟内存空间
. 那么就可以让两个进程各自拿出一块虚拟地址空间来, 然后映射到相同的物理内存中, 这样, 两个进程虽然有独立的虚拟内存空间, 但是一部分却是映射到相同的物理内存, 这样就完成了 内存共享 机制 - 共享内存又有什么问题呢
- 当你一块物理内存空间能够被多个进程读取的时候, 问题就来了, 那就是多线程竞争的问题, 那么如何解决呢?
4 . 信号量
- 信号量的本质就是一个计数器, 用来实现进程之间的互斥和同步, 例如信号量的初始值是 1 , 然后进程 1 进来访问 内存1 的时候, 五年就把信号量设置为 0, 然后 进程2 也来访问 内存1 的时候, 看到信息量为 0 的时候, 就知道该线程已经被占用, 就无法访问 内存1, 所以, 信号量也是进程间的一种通信方式
5 . Socket
- 上面说的都是一台机器内部的进程通信, 那么网络上进程如何通信呢?
- Socket , 通过浏览器发起一个 http 请求, 然后服务器给你返回对应的数据, 这种就是采用 Socket 的通信方式