每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都是看不到的,所以进程间要交换数据必须通过内核,在内核中开辟一个缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC, InterProcess Communication)。
管道
管道是一种最基本的IPC机制,由pipe函数创建, pipe函数在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端和一个写端。
1 |
|
fd[0]指向管道的读端,fd[1]指向管道的写端。管道在用户程序看来就像一个打开的文件,通过read(fd[0])或者write(fd[1])向这个文件读写数据其实是在读写内核缓冲区。pipe函数调用成功返回0,调用失败返回-1.
FIFO
FIFO有时候被称为命名管道,未命名的pipe只能在两个相关的进程间通信,FIFO可以用在不相关的进程间通信。FIFO有如下两种用途:
- Shell命令使用FIFO将数据从一条管道传递到另一条时,无需创建中间临时文件
- 客户端-服务器进程应用中,FIFO用作汇聚点,在客户进程和服务器进程之间传递数据
进程之间传递信息的途径总结如下:
- 父进程通过fork将打开的文件描述符传递给子进程
- 子进程结束时,父进程调用wait可以得到子进程的终止信息
- 几个进程可以在文件系统中读写某个共享文件,也可以通过给文件加锁来实现进程间同步
- 进程之间互发信号,一般使用SIGUSR1和SIGUSR2实现用户自定义功能
- 管道
- FIFO
- 通过mmap函数,几个进程可以映射同一内存区
- SYS V IPC,包括消息队列、信号量和共享内存,现在已经基本废弃
- UNIX Domain Socket,目前最广泛使用的IPC机制
参考资料
《Linux C编程一站式学习》
《Unix环境高级编程》