Linux 管道通信详解
一、进程间通信基础
进程间通信(IPC)的核心在于不同进程之间的信息交换,包括数据传输、资源共享、事件通知和进程控制等。
常见的 IPC 方式有管道、System V IPC 和 POSIX IPC。由于进程具有独立性,实现通信的前提是这些进程能够访问同一份共享资源。
二、管道机制
1. 什么是管道
管道是类 Unix 系统中最古老的 IPC 方式之一。简单来说,它将一个进程的输出连接到另一个进程的输入,形成一条数据流通道。
管道是单向通信的,即单工模式。根据创建方式和适用范围,主要分为匿名管道和命名管道。
2. 匿名管道
匿名管道(pipe)主要用于有亲缘关系的进程之间(如父子进程)。它本质上是内核管理的一块内存区域,通过一对文件描述符实现读写分离。管道随进程退出自动销毁,没有文件名,因此称为'匿名'。
使用 pipe 系统调用创建管道,参数是一个包含两个整数的数组。通常 fd[0] 为读端,fd[1] 为写端。
关键点:
- 只能用于有血缘关系的进程,因为需要继承文件描述符表。
- 面向字节流,多次写入的数据可能被一次读取或分多次读取。
- 自带同步互斥:读空阻塞,写满阻塞。
- 生命周期随进程,所有持有者关闭后自动销毁。
下面是一个简单的父子进程通信示例,子进程向父进程发送消息:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
int pipefd[2] = {0};
if (pipe(pipefd) != 0) {
exit(1);
}
// pipefd[0] 是读端,pipefd[1] 是写端
printf("pipefd[0]: %d, pipefd[1]: %d\n", pipefd[0], pipefd[]);
id = fork();
(id == ) {
(pipefd[]);
* msg = ;
cnt = ;
outbuffer[];
(cnt) {
(outbuffer, (outbuffer), , msg, cnt--);
(pipefd[], outbuffer, (outbuffer));
();
}
(pipefd[]);
();
} {
(pipefd[]);
inbuffer[];
() {
inbuffer[] = ;
n = (pipefd[], inbuffer, (inbuffer) - );
(n > ) {
inbuffer[n] = ;
(, inbuffer);
} (n == ) {
();
(pipefd[]);
;
} {
();
;
}
}
(id, , );
}
;
}


