1:要求实现父子进程对话
1.父进程先发送一句话给子进程,子进程接收后打印
2.子进程再回复一句话给父进程,父进程接收后打印
3.重复1.2步骤,当收到quit后,要结束父子进程
程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(int argc, const char *argv[])
{
//创建无名管道
int pfd[2]={0};
if(pipe(pfd)<0)
{
perror("pipe");
return -1;
}
int pfd1[2]={0};
if(pipe(pfd1)<0)
{
perror("pipe");
return -1;
}
char buf[]="quit";
char buf1[128]="";
ssize_t res=0;
//创建子进程
pid_t pid=fork();
if(pid>0) //父进程为真,子进程为假
{
while(1)
{
//从终端获取数据
bzero(buf1,sizeof(buf1));
waitpid(pid,NULL,WNOHANG);
fgets(buf1,sizeof(buf1),stdin);
buf1[strlen(buf1)-1]='\0';
if(strcmp(buf1,buf)==0)
{
printf("退出\n");
exit(0);
}
//发送给子进程
if((res=write(pfd[1],buf1,sizeof(buf1)))<0)
{
perror("write");
return -1;
}
bzero(buf1,sizeof(buf1));
//读取子进程发送过来的数据
//当管道中没有数据的时候read函数阻塞
res=read(pfd1[0],buf1,sizeof(buf1));
if(res<0)
{
perror("read");
return -1;
}
printf("子进程说:%s\n",buf1);
}
}
else if(pid==0)
{
while(1)
{
bzero(buf1,sizeof(buf1));
//读取父进程发送过来的数据
//当管道中没有数据的时候read函数阻塞
res=read(pfd[0],buf1,sizeof(buf1));
if(res<0)
{
perror("read");
return -1;
}
printf("父进程说:%s\n",buf1);
//从终端获取数据
bzero(buf1,sizeof(buf1));
fgets(buf1,sizeof(buf1),stdin);
buf1[strlen(buf1)-1]='\0';
if(strcmp(buf1,buf)==0)
{
printf("退出\n");
exit(0);
}
//发送给父进程
if((res=write(pfd1[1],buf1,sizeof(buf1)))<0)
{
perror("write");
return -1;
}
}
}
return 0;
}
运行效果:
qwwe
父进程说:qwwe
fwefeefg
子进程说:fwefeefg
quit
退出
2:为什么无名管道只能用于具有 亲缘关系 的进程间通信。(个人理解)
1:亲缘进程他们用户空间相互独立,但是内核空间共享,而无名管道是一个特殊的文件,存在于内核空间
2:无名管道在fork函数前创建,foek函数调用的一瞬间,父子进程资源一样,包括文件描述符,而无名管道也是文件,也有文件描述符,所以亲缘进程都能访问。