进程间的通信方式
管道
概念:管道其实就是内核中一串缓存,从管道的一端写入,实际就是缓存在内核中(必须等到管道内的数据被读取才能退出,所以不适合用作数据交换频繁的场景),另一端读取,也就是从内核中读取这一段数据(实则是两个文件描述符)
匿名管道
定义:适应于父子进程(具有亲缘关系的进程)之间的通信方式
有名管道
概念:不具有亲缘关系的进程之间的通信方式
缺点
- 不适用用于频繁的数据交换(因为要等到数据被读取才能返回)
- 大小有限制而且是没有消息格式的
消息队列
概念:消息队列就是保存在内核中的消息链表,在发送时,会分成一块一块的数据单元,也就是消息体,消息体是可以自定义的,发送方和接收方要约定好发送消息的格式
优点
- 改变了管道中必须等待返回的缺点,只要将消息放下就可以返回
- 发送和接收双方可以自定义消息体,不像管道的二进制格式
缺点
- 消息发送不及时
- 存在用户态和内核态的拷贝(因为是存在内核区的缓存)
- 附件大小也是有大小限制的
共享内存
概念:就是拿出一块虚拟地址空间,映射到相同的物理地址上,这样就不存在用户和内核态的拷贝对资源进行损耗
信号量
概念:解决共享内存产生竞态资源的问题,信号量其实是一个整型的计数器,主要用于实现进程间的互斥和同步
原子操作
- P操作:这个操作会将信号量-1,相减后如果信号量<0,则证明该资源已经被占用了,进程需要等待
- V操作:这个操作会将信号量+1,相加后若是还小于0证明其中还有进程,若是大于0证明临界资源可以被使用了
信号
概念:在操作系统中,为了响应各种各样的事件,提供了几十种信号,分别代表不同的意义(是进程通信中唯一一中异步通信机制)例如:Ctrl+C就是产生一个SINGINT表示终止这个进程
进程对信号的处理方式
- 默认信号:操作系统对每一种信号都规定了默认操作
- 捕抓信号:我们可以自己定义一个信号函数,但是信号发生的时候,执行相应的函数
- 忽略信号:当我们不希望处理某些信号的时候,就可以忽略该信号
Socket通信
TCP通信
UDP通信
本机进程通信
- 本地字节流socket:其 socket 类型是 AF_LOCAL 和 SOCK_STREAM
- 本地数据包socket:其socket 类型是 AF_LOCAL 和 SOCK_DGRAM
- 本地字节流 socket 和 本地数据报 socket 在 bind 的时候,不像 TCP 和 UDP 要绑定 IP 地址和端口,而是绑定⼀个本地⽂件,这也就是它们之间的最⼤区别。