案例要求
使用管道来实现兄弟间通信,完成ls | wc -l
统计当前目录下文件个数,父进程回收子进程
分析
要使用dup2
函数把原本的标准输出改为输出到管道的缓冲区中。
父进程不执行写和读操作,故父进程要把读和写都关闭
代码实现
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
// 管道通信,for循环生成子进程,两个进程通信
//兄进程写,弟进程读,父进程来回收
int main(){
int i;
pid_t pid;
int fd[2];
int ret = pipe(fd);
//判断管道是否创建成功
if( ret == -1){
perror("pipe");
exit(1);
}
//循环生成子进程
for(i = 0;i < 2; i++){
//新建子进程
pid = fork();
//判断进程否创建成功
if( pid == -1){
perror("pipe");
exit(1);
}
//子进程退出
else if (pid == 0){
break;
}
}
//利用循环因子i来判断子进程
//i = 0为兄进程
if( i == 0 ){
//关闭读
close(fd[0]);
//复制文件描述符,将文件从标准输出到管道缓冲区
dup2(fd[1],STDOUT_FILENO);
//执行ls指令(以NULL作为哨兵结束)
execlp("ls","ls",NULL);
}
//i = 1为弟进程
else if( i == 1 ){
//关闭写
close(fd[1]);
//复制文件描述符,将文件从标准输入到管道缓冲区
dup2(fd[0],STDIN_FILENO);
//执行wc -l指令(以NULL作为哨兵结束)
execlp("wc","wc","-l",NULL);
}
//父进程回收子进程-->两个子进程回收两次
else {
close(fd[1]);
close(fd[0]);
for(int j = 0; j < 2; j++ ){
wait(NULL);
}
}
return 0;
}
结果图
案例要求
使用管道来实现父子间通信,完成ls | wc -l
统计当前目录下文件个数
分析
要使用dup2
函数把原本的标准输出改为输出到管道的缓冲区中。
父进程写的子进程读的话,父进程写完就执行完毕,这个时候函数会变成僵尸进程,故应该把父进程设置为读,子进程写
代码实现
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
// 管道通信,for循环生成子进程,两个进程通信
int main(){
//fork函数状态
pid_t pid;
//用于保存文件描述符
int fd[2];
//新建管道返回值
int ret = pipe(fd);
//新建子进程
pid = fork();
//判断管道是否创建成功
if( ret == -1){
perror("pipe");
exit(1);
}
//判断进程否创建成功
if( pid == -1){
perror("pipe");
exit(1);
}
//父进程读(关闭写端)
else if( pid > 0){
close(fd[1]);
//利用dup2将文件描述符从标准输出,改为输出到管道缓冲区中
dup2(fd[0],STDIN_FILENO);
//执行ls命令
execlp("wc","wc","-l",NULL);
}
//子进程写(关闭读端)
else {
close(fd[0]);
//利用dup2将文件描述符从标准输出,改为输出到管道缓冲区中
dup2(fd[1],STDOUT_FILENO);
//执行ls命令
execlp("ls","ls",NULL);
}
return 0;
}