Linux 系统编程之管道通信-父子进程实现pipe通信
例程:实现 ps aux | grep bash
#include<stdio.h>
#include<unistd.h>
int main()
{
int fd[2];
pipe(fd);
pid_t pid=fork();
if(pid == 0)
{
//son --ps
//1.重定向
//2.execlp函数
dup2(fd[1],STDOUT_FILENO);//标准输出重定向到管道写端
execlp("ps","ps","aux",NULL);
}
else if(pid>0)
{
//parent
//先重定向,标准输入重定向到管道的读端
dup2(fd[0],STOIN_FILENO);
//execlp
execlp("grep","grep","bash"NULL);
}
}
如果这么些写会出现僵尸进程,(没有wait,而且 父进程还没退;)
代码问题:
父进程认为还有写端存在,就有可能还有人给发数据,继续等待
修改
如果父进程负责读,就将写关掉,子进程关掉读
```bash
#include<stdio.h>
#include<unistd.h>
int main()
{
int fd[2];
pipe(fd);
pid_t pid=fork();
if(pid == 0)
{
//son --ps
// 关闭读端
close(fd[0]);
//1.重定向
//2.execlp函数
dup2(fd[1],STDOUT_FILENO);//标准输出重定向到管道写端
execlp("ps","ps","aux",NULL);
}
else if(pid>0)
{
//parent
//关闭写端
close(fd[1]);
//先重定向,标准输入重定向到管道的读端
dup2(fd[0],STOIN_FILENO);
//execlp
execlp("grep","grep","bash"NULL);
}
}
输出:
这样就不会阻塞了,所以一定注意管道数据流向是单向的
缺点,父进程无法回收子进程,实现 ps -aux | grep bash 最好使用兄弟间进程
使用兄弟间进程通信,实现ps aux|grep bash
#include<stdio.h>
#include<unistd.h>
int main()
{
int fd[2];
int i=0;
pipe(fd);
for(i=0;i<2;i++)
{
pid_t pid=fork();
if(pid==0)
{
break;
}
}
if(i == 0)
{
//son --ps
// 关闭读端
close(fd[0]);
//1.重定向
//2.execlp函数
dup2(fd[1],STDOUT_FILENO);//标准输出重定向到管道写端
execlp("ps","ps","aux",NULL);
}
else if(i==1)
{
//son --grep
//关闭写端
close(fd[1]);
//先重定向,标准输入重定向到管道的读端
dup2(fd[0],STOIN_FILENO);
//execlp
execlp("grep","grep","bash"NULL);
}
else
{
close(fd[0]);
close(fd[1]);
pid_t wpid;
while( (wpid = waitpid(-1, NULL, WNOHANG)) != -1 )
{
if(wpid == 0)
{
continue;
}
printf("died child pid = %d\n", wpid);
}
}
return 0;
}
- 子1进程实现ps aux , 写管道,需要关闭读端。
- 子2进程实现grep bash ,从管道中读,需要关闭写端。
- 整个程序实现了ps aux | grep "bash"的功能。
- 父进程用来回收子进程的资源。