创建匿名管道
本质:
- 内核缓冲区,伪文件,不占用磁盘空间,默认4k
特点:
- 分为两部分 读端,写端
- 读端流出,写端流入.
- 操作管道的进程被销毁之后,管道自动被释放.
- 管道默认是阻塞的,读阻塞,写阻塞
实现方式:
- 环形队列.一个队尾, 一个队头.从队尾进入,队头出
局限性:
- 数据只能读取一次,不能重复读取
- 数据是半双工, 从一方写入,另一方流出
匿名管道:
仅适用于有血缘关系的进程通讯.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc,char *argv[])
{
int pipefd[2];
char buf[100];
int ret = 0;
pid_t fp;
ret = pipe(pipefd);
if(0 != ret)
{
perror("pipe"),exit(0);
}
fp = fork();
if(fp < 0)
{
perror("fork"),exit(0);
}
else if(0 < fp)
{
printf("this is in the father process,write a string to the pipe...\n");
char str[] = "hi,my child,i am your father";
write(pipefd[1],str,sizeof(str));
sleep(1);
close(pipefd[0]);
close(pipefd[1]);
}
else
{
printf("this is in the child process,read a string from the pipe...\n");
read(pipefd[0],buf,sizeof(buf));
printf("read : %s\n",buf);
sleep(1);
close(pipefd[0]);
close(pipefd[1]);
}
waitpid(fp,NULL,0);
return 0;
}
实现 管道的功能
- 如 ps aux | grep bash命令
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
//本功能实现的是 ps axu |grep bash
//通过调用 ps 和 grep命令 ,然后分别将他们的输出 和 输入的文件描述符改变. 从终端改入到管道中.
int main(int argc,char *argv[])
{
int fd[2];
//创建管道
//fd[0]为读端 fd[1]为写端
int ret = pipe(fd);
if(ret == -1){
perror("pipe error");
exit(1);
}
pid_t pid = fork();
if(pid == -1){
perror("fork error");
exit(1);
}
//父进程 ps aux 子进程执行 后半段 grep "bash"
if(pid > 0){
//父进程写入管道, 关闭读端
close(fd[0]);
//文件描述符的重定向
//stdout_fileno指向到 管道的写端
dup2(fd[1], STDOUT_FILENO);
//执行ps aux
execlp("ps", "ps", "aux", NULL);
perror("execlp");
exit(1);
}else if(pid == 0){
//子进程
//子进程做的是读管道操作,关闭写端
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
execlp("grep", "grep", "bash", "--color=auto", NULL);
}
printf("pipe[0]= %d\n", fd[0]);
printf("pipe[1]= %d\n", fd[1]);
close(fd[0]);
close(fd[1]);
return 0;
}