无名管道的特点
无名管道属于单向通讯
无名管道只能用于父子进程通讯
无名管道发送端叫做写端,接收端叫做读端
无名管道将读端与写端抽象成两个文件进行操作,在无名管道创建成功之后,则会将读端与写端的文件描述符存入数组
创建无名管道
pipe()
#include <unistd.h>
int pipe(int pipefd[2]);
功能
管道创建之后,内核会将文件描述符存储到数组
函数参数
pipefd:用于存储无名管道读端与写端的文件描述符的数组
pipefd[0]:读端文件描述符
pipefd[1]:写端文件描述符
函数返回值
成功:0
失败:-1,设置 errno
示例代码
创建一个子进程,负责循环从管道中读取数据,父进程从键盘读取数据后,写入到管道中,输入 “quit” 字符
串时退出
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int pipefd[2];
pid_t pid;
char buf[1024];
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]);
while (1) {
memset(buf,0,strlen(buf));
ssize_t n = read(pipefd[0], buf, sizeof(buf));
if (n <= 0||(strncmp(buf,"quit",4)==0)) {
printf("fork 退出!\n");
break;
}
putchar('\n');
printf("子进程接收到: %s\n", buf);
}
close(pipefd[0]);
exit(EXIT_SUCCESS);
} else {
close(pipefd[0]);
while (1) {
memset(buf,0,strlen(buf));
printf("请输入要发送的数据(输入 'quit' 退出):");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1]='\0';
write(pipefd[1], buf, strlen(buf));
if (strncmp(buf, "quit", 4) == 0) {
close(pipefd[1]);
break;
}
}
wait(NULL);
}
return 0;
}