Linux 使用pipe实现父子进程持续通信

提示:

       首先要知道Linux使用管道无法实现双向通信,可以调用pipe创建两个管道,一个用于父进程写,子进程读;一个用于子进程写,父进程读   

    其次,pipe只用于两个有联系的管道通信,而且是剪切性读,读取的长度一定要算对,如strlen(msg)+1不要忘记末尾的’\0’

    若管道有数据,读取成功,剪切走,再次读取将阻塞,直到管道中有写入的数据;

    若管道中没有数据,写入成功,粘贴上,再次写入将阻塞,直到管道中的数据被读走

 

pipe使用步骤

1.     父进程中调用piep创建管道,fd[0]用于读,fd[1]用于写

2.     父进程中调用fork创建子进程

3.     父进程关闭写,打开读;子进程关闭读,打开写

代码如下:

调用了很多printf有利于大家理解,可以删除多余printf,甚至阻塞标志

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
int fd[ 2];
int pid,line;
char msg[BUFSIZ];
//阻塞标志
int parentFlag = 1;// 1阻塞 2不阻塞
int childFlag = 1;// 2阻塞 1不阻塞

printf( "程序开始 \n ");
if( pipe(fd) < 0 ){
perror( "创建管道失败:");
}
printf( "创建管道成功 \n ");

pid = fork();
if( pid < 0){
perror( "创建进程失败");
exit( 1);
} else if(pid == 0){
printf( "子进程开始 \n ");
printf( "1子进程写入: \n ");
while( 1 ){
if(childFlag== 2){
childFlag= 1;
printf( "子进程阻塞,进入父进程 \n\n ");
} else{
childFlag++;
}
scanf( "%s",msg);

close(fd[ 0]); //关闭读
write(fd[ 1],msg, strlen(msg)+ 1); //开始写
printf( "子进程写入完成 \n\n ");
if ( strcmp(msg, "EOF") == 0){
printf( "子进程结束通信 \n ");
break;
}
} //while

printf( "子进程结束 \n ");
_exit( 0);
} else{
printf( " \n 父进程开始 \n ");
while( 1 ){
if(parentFlag== 1){
parentFlag++;
printf( "父进程阻塞,进入子进程 \n\n ");
}
if(childFlag== 2) {
printf( "2子进程写入: \n ");
} else{
childFlag= 2;
}

close(fd[ 1]); //关闭写
read(fd[ 0],msg,BUFSIZ); //开始读

if(parentFlag== 2){
parentFlag= 1;
printf( "父进程解除阻塞 \n ");
printf( "父进程开始读取 \n ");
printf( "父进程读取:%s \n ",msg);

if ( strcmp(msg, "EOF") == 0){
printf( "父进程结束通信 \n ");
break;
}
printf( "父进程读取完成 \n\n ");
}
} //while
wait( NULL); //等待子进程执行完
     printf( "父进程结束 \n ");
}
printf( "程序结束 \n ");
return 0;
}

结果:


GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐