在 Linux 系统中,管道是一种常见的 IPC(进程间通信)形式,用于在两个进程之间传递数据。管道可以分为匿名管道和命名管道。
匿名管道是一种半双工的通信方式,数据只能单向流动,而且只在具有亲缘关系的进程间有效。
以下是创建匿名管道并使用它进行通信的示例代码:
父进程代码(pipe\_parent.c):
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
const char *msg = "Hello, child!\n";
// 父进程写入数据
if (write(pipefd[1], msg, strlen(msg)) == -1) {
perror("write");
close(pipefd[0]);
close(pipefd[1]);
exit(EXIT_FAILURE);
}
char buf[100];
ssize_t bytes_read;
// 读取子进程发送的数据
bytes_read = read(pipefd[0], buf, sizeof(buf) - 1);
if (bytes_read == -1) {
perror("read");
close(pipefd[0]);
close(pipefd[1]);
exit(EXIT_FAILURE);
}
buf[bytes_read] = '\0';
printf("Parent received: %s", buf);
close(pipefd[0]);
close(pipefd[1]);
return 0;
}
子进程代码(pipe\_child.c):
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
char buf[100];
ssize_t bytes_read;
// 读取父进程发送的数据
bytes_read = read(pipefd[0], buf, sizeof(buf) - 1);
if (bytes_read == -1) {
perror("read");
close(pipefd[0]);
close(pipefd[1]);
exit(EXIT_FAILURE);
}
buf[bytes_read] = '\0';
printf("Child received: %s", buf);
const char *msg = "Hello, parent!\n";
// 子进程写入数据
if (write(pipefd[1], msg, strlen(msg)) == -1) {
perror("write");
close(pipefd[0]);
close(pipefd[1]);
exit(EXIT_FAILURE);
}
close(pipefd[0]);
close(pipefd[1]);
return 0;
}
在这个例子中,父进程和子进程通过一个匿名管道进行了数据交换。父进程创建管道,得到两个文件描述符指向管道的两端,一个用于读取(pipefd[0]),一个用于写入(pipefd[1])。子进程通过继承或通过其他方式获得管道文件描述符后,也可以进行类似的读写操作。
管道通信的原理是:数据在管道中以字节流的形式传输,读写操作是按照字节或数据块进行的。管道一般用于两个具有亲缘关系的进程之间的通信,这些进程可以是父子进程或兄