一 上一节补充
匿名管道
为什么读写端是 分别 3 4 呢
读写端会接到 3的后面 所以 为 3 4
因为都是属于标准库的
二 父子进程管道通信
注意 读写中进行一个时 另外一个关闭
左右两个都为进程
1 这里是先管道 有数据 后 才创建父子进程 ???
先做一个实验
先 调用 fork 函数
后 pipe函数
#include<stdio.h>
#include<unistd.h>
#include<stdib.h>
#include<sys/types.h>
int main()
{
int arr[2];
pid_t aa;
pid_t ff;
aa=frok();
ff=pipe(arr);
if(ff==-1)
{
printf("pipe is error\n");
return -2;
}
if(aa>0)
{
printf("father pid is%d\n",getpid());
}
else if(aa==0)
{
printf("father pid is%d ppid is %d\n",getpid(),getppid());
}
printf("fd[0]===%d\n",arr[0]);
printf("fd[1]===%d\n",arr[1]);
return 0;
}
结果不输出
得到一个结论
1 是先创建管道才创建父子进程的
用这个方法不能进行父子通信
怎么解决
2 要 重定向(dup2函数) 才行
重定向就是换个名字
也就是父进程 换成变成管道 就行了
改变输入位置
2 ps aux | grep “bash”
ps aux | grep “bash” 分解 可为下列含义
1 ps aux :父进程
2 grep “bash”:子进程
3 | 管道
按照重定向意思
1 把父进程 换成 管道 (换了名字)
2 子进制读取数据
中间会用到execlp函数
execlp函数 适用于有固定的命令参数和命令名字
(不是用户创建的,是内核本身存在的指令数据)
比如 ls -l
再比如 ps aux | grep “bash”
直接上代码
#include<stdio.h>
#include<unistd.h>
#include<stdib.h>
#include<sys/types.h>
int main()
{
int arr[2];
pid_t aa;
pid_t ff;
aa=frok();
ff=pipe(arr);
if(ff==-1)
{
printf("pipe is error\n");
return -2;
}
if(aa>0)
{
close(arr[0]);
dup2(arr[1],STDOUT_FILENO);
execlp("ps","ps","aux",NULL);
printf("father pid is%d\n",getpid());
}
else if(aa==0)
{
close(arr[1]);
dup2(arr[0],STDIN_FILENO);
execlp("grep","grep","bash",NULL);
printf("father pid is%d ppid is %d\n",getpid(),getppid());
}
printf("fd[0]===%d\n",arr[0]);
printf("fd[1]===%d\n",arr[1]);
return 0;
}
这里的bash的内容是子进程的 也是父进程写进去,
因为父进程 是从main开始执行
所以编译只能看到父进程写的 内容
ps aux | grep “bash”
子进程读取管道数据
因为前面管道写入了 grep bash
而 grep只是一个命令名字 那么数据就是 bash
所以子进程读取的就是管道写的数据 bash
|