pipe函数用于创建一条匿名管道,在具有亲缘关系的进程(如父子进程)之间进行通信,pipe() 函数会生成一对文件描述符,分别用于管道的读和写操作;由于管道传输是半双工的,数据只能在单个方向上流动,父进程往子进程传数据时,父进程的管道读端和子进程的管道写端都可以先关闭。
1.头文件
#include <unistd.h>
2.函数原型
int pipe(int pipefd[2]);
3.参数
pipefd:一个包含两个整数的数组,用于存储 pipe() 创建的两个文件描述符。
pipefd[0]:用于从管道中读取数据(读端)。
pipefd[1]:用于向管道中写入数据(写端)。
4.返回值
成功,返回 0。失败,返回 -1。
5.示例:通过pipe()函数创建匿名管道通信
| #include <stdio.h>
#include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> int main() { int pipefd[2]; pid_t pid; char buffer[128]; // 创建管道 if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } // 创建子进程 pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (pid == 0) { // 子进程 close(pipefd[1]); // 关闭写端 read(pipefd[0], buffer, sizeof(buffer)); // 从管道读端读取数据 printf("The child process receives the data:%s\n", buffer); close(pipefd[0]); // 关闭读端 exit(EXIT_SUCCESS); } else { // 父进程 close(pipefd[0]); // 关闭读端 const char *msg = "Hello from parent process!"; write(pipefd[1], msg, strlen(msg) + 1); // 向管道写端写入数据 close(pipefd[1]); // 关闭写端 wait(NULL); // 等待子进程结束 exit(EXIT_SUCCESS); } } |
6.运行结果
| The child process receives the data:Hello from parent process! |
7.代码解析
使用pipe()创建管道,匿名管道创建成功以后,创建该匿名管道的进程(父进程)同时掌握着管道的读取端和写入端,调用fork()创建子进程,子进程会复制父进程的内存空间,包括文件描述符(子进程在生成时会获得父进程所有的文件描述符的副本,包括管道的读端(pipefd[0])和写端(pipefd[1]))。父子进程分别执行接下来的程序,子进程中调用close()函数关闭写描述符,父进程相应的关闭读描述符;子进程调用read()函数读取管道内容,如果管道没有数据则子进程将被阻塞,读取到数据就将数据打印出来,然后关闭读端;父进程调用write()函数将数据写入管道。关闭父进程写描述符。调用wait()函数等待子进程退出。
177