1. 管道
-
无名管道:只能在父子进程或具有继承关系的进程之间单工通信。
原理:管道是内核管理的缓冲区,两端连接两个进程:一个负责读,一个负责写。读的时候管道空或写的时候管道满,会产生阻塞。两个进程都撤销时,管道也随之消失,建立前确保双方存在,否则退出。
typo:pipeline
- 流管道:只能父子间进行半双工通信
- 有名管道(named pipe):FIFO是一种特殊的文件类型,该文件有对应路径,因此不同进程可以通过路径名访问该文件,以此为载体实现跨进程通信,建立前双方如果有一方不存在则阻塞,而不是退出。
2. 信号
Linux用于进程互相通信的机制,信号可以在任何时候发给某进程而无需知道对方进程的状态。
来源:信号是软件层面上对中断的模拟,是一种异步通信方式,信号可以在内核态和用户态之间来回交互。信号的传递由系统完成。主要来源两方面,硬件,如CTRL+C,硬件异常;软件:kill命令,除零错误。
常用信号:
- SIGINT: Ctrl+C产生,键盘中断
- SIGKILL: kill -9 产生,用户终止进程
- SIGTERM:kill pid产生,结束进程
- SIGHUB: 用户从终端退出
3. 消息队列MQ:链表,存放在内核中,由队列id标识,与FIFO相似,但关键区别在于:
- 进程向消息队列写数据时不要求另一个进程在该队列上等待读消息。但FIFO要求写消息时另一端必须有进程打开,否则内核产生SIGPIPE信号。
- 持久性:FIFO与进程持久,进程消失,有名管道也消失;消息队列与内核持久,驻留内存。因此进程读消失时可能会读到上次进程残留的消息,读写时要注意这点。
它们共同点都是有大小限制。
4. 共享内存
管道、FIFO、消息队列的共同特点是通过内核通信。
共享内存的原理是把内存中一块区域映射到欲通信的进程地址空间里,进程对这块内存操作即可。
5. 套接字
socket用于远程主机间的通信,当然本机之间也可以。使用五元组来标识一个socket连接。
socket := <source_ip, source_port, dest_ip, dest_ip, protocol>
相关原理查网络编程