linux进程间的通信方式?
每个进程的用户地址空间都是相互独立的,一般不能互相访问,但是内核空间是共享的,所以进程之间的通信必须经过内核。
1、管道
管道是最简单的进程间通信方式,分为匿名管道和命名管道,但是管道通信效率低,不适合频繁的交换顺序。
- 匿名管道:通信范围是存在父子关系的进程。
- 命名管道:通信范围可以是不相关的进程。
2、消息队列
详细队列是保存在内核中的消息链表,通信方式类似于发邮件。
优点:
- 可以频繁交换数据
缺点:
- 邮件模式会造成通信不及时,附件大小也会有限制,不适合比较大的数据传输、
- 存在用户态与内核态之间的数据拷贝开销。
3、共享内存
共享内存是进程各自用一块虚拟地址空间,映射到相同的物理内存中。解决用户态与内核态之间的数据拷贝过程。
缺点:
- 如果多个进程同时修改同一个共享内存,会出现数据错乱。
4、信号量
信号量解决共享内存机制中多进程资源竞争的问题,提供一种保护机制,使得共享的资源,在任意时刻只能被一个进程访问。
信号量其实是一个整型计数器,用于实现进程间的互斥与同步,而不是用于缓存进程间通信的数据。
(1)P-V操作
信号量s
表示资源的数量,有两种原子操作:P-V
操作。
P
:s-1
,表示进入共享资源之前。V
:s+1
,退出共享资源以后。
(2)P-V
操作实现互斥同步
- 互斥:信号量初始
s=1
- 同步:信号量初始
s=0
5、信号
信号主要是针对异常情况下的工作方式,通过信号来通知进程。
信号是进程间通信的唯一一个异步通信机制。
6、socket通信
管道、消息队列、共享内存、信号量、信号主要是在同一台主机上的进程间通信,如果要夸网络与不同主机上的进程之间通信,则需要使用socket
通信。socket
当然也可以在同一主机上进的进程间信。
(1)TCP协议通信的Socket编程模型
server
和client
初始化socket
,得到文件描述符。server
调用bind
,绑定ip:port
。server
调用listen
,进行监听。server
抵用accept
,等待客户连接。client
调用connect
,向server
的[ip:port]
发送连接请求。server
的accept
返回用于传输的socket
的文件描述符。client
调用write
写入数据,server
调用read
读取数据。client
断开连接时,调用close
,server
用read
读取数据的时候,会读取EOF
,待server
处理完数据后,server
也会用close
关闭连接。
注:服务端调用 accept
时,连接成功了会返回一个已完成连接的 socket,后续用来传输数据。
所以,监听的 socket 和真正用来传送数据的 socket,是「两个」 socket,一个叫作监听 socket,一个叫作已完成连接 socket。
(2)UDP协议通信的Socket编程模型

-
UDP是无连接的,所以不需要像TCP建立连接过程,只需要
bind
绑定[ip:port]
端口号 -
对于 UDP 来说,不需要要维护连接,那么也就没有所谓的发送方和接收方,甚至都不存在客户端和服务端的概念,只要有一个 socket 多台机器就可以任意通信,因此每一个 UDP 的 socket 都需要 bind。
-
每次通信时,调用 sendto 和 recvfrom,都要传入目标主机的 IP 地址和端口。