在UNIX和Linux操作系统中,进程间通信(IPC - Interprocess Communication)是实现多个并发执行的进程之间交换数据的重要机制。这种通信方式允许不同进程协同工作,共同完成复杂的任务。本讲义主要涵盖了IPC的概述、类型、持续性,以及重点讨论了管道(Pipe)这一常见的IPC形式。
1. IPC概述:
IPC主要指的是一些特定的机制,让运行在同一操作系统上的不同进程能够相互通信。这些机制包括管道、消息队列、共享内存等。在某些情况下,IPC也涉及跨主机进程间的消息传递,如套接字(Socket)和远程过程调用(RPC)。
1.1 IPC的类型:
- 消息传递:如管道、FIFO(命名管道)、消息队列
- 同步:包括互斥锁、条件变量、读写锁、文件与记录锁、信号灯
- 共享内存区:匿名共享内存和有名共享内存
- 远程过程调用:如Solaris门和SUN RPC
1.2 IPC对象的持续性:
- 随进程持续:如管道、FIFO,持续到最后一个使用它的进程关闭
- 随内核持续:如System V消息队列、信号灯、共享内存,直到内核重启或显式删除
- 随文件系统持续:如Posix消息队列、信号灯、共享内存,即使内核重启,仍保持其值
2. 管道:
2.1.1 管道特性:
- 管道是最早的UNIX IPC形式之一,所有UNIX系统都支持
- 半双工,只能单向传输,全双工通信需两个管道或使用socketpair()
- 通常用于具有亲缘关系(父子进程或兄弟进程)的进程间通信
- S_ISFIFO()宏检查文件是否为管道或FIFO
- 无文件定位操作,如lseek()
2.1.2 管道创建与使用:
- 管道通过描述字fd[0](读端)和fd[1](写端)表示
- 不能反向操作,即不能从写端读或向读端写
- 使用标准I/O函数如close(), read(), write()等操作管道
- 创建管道通常通过系统调用pipe()
2.3 管道的读写规则:
- 读取:若写端不存在,读函数返回0;若写端存在,根据请求的字节数和管道中的实际数据决定读取量
- 写入:非原子性,一旦有空间立即尝试写入,若读端不存在,进程会收到SIGPIPE信号
管道的限制在于其半双工性质和有限的缓冲区大小(通常为PIPE_BUF字节),因此在多进程协作时,可能需要其他更复杂的IPC机制,如消息队列或共享内存,以实现更灵活的数据交换和同步。理解并熟练掌握这些机制对于进行高效、可靠的多进程程序设计至关重要。学习UNIX/Linux IPC不仅有助于开发者更好地理解操作系统的工作原理,还能提升他们在系统级编程领域的专业能力。