代码实际上做的是从父进程获取输入,通过管道将其发送到子进程。子进程将其反转,然后通过另一个管道将其发送回父级。代码中没有waitpid()
或wait()
函数。
问题是:流程切换如何在这里工作? write()
和read()
函数如何在这里工作?
以下是代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <iostream>
#define li long int
using namespace std;
void ReverseAString(char input[])
{
li length = strlen(input),i;
char hold;
for(i=0;i<length/2;i++)
{
hold = input[i];
input[i] = input[length-(i+1)];
input[length-(i+1)] = hold;
}
}
int main()
{
pid_t ChildOrParentId;
int fifoParent[2],fifoChild[2],in;
if(pipe(fifoParent)==-1)
{
cout<<"Problem in creating Parent's Pipe"<<endl;
perror("Parent's Pipe");
exit(1);
}
if(pipe(fifoChild)==-1)
{
cout<<"Problem in creating Child's Pipe"<<endl;
perror("Child's Pipe");
exit(1);
}
ChildOrParentId = fork();
if(ChildOrParentId==0)
{
char buf[100],collected[100];
close(fifoParent[0]);
close(fifoChild[1]);
in = 0;
while(read(fifoChild[0],buf,1)>0)
{
collected[in]=buf[0];
in++;
}
collected[in]=0;
cout<<"Read from Child "<<collected<<endl;
ReverseAString(collected);
cout<<"After Reversing: "<<collected<<endl;
write(fifoParent[1],collected,sizeof(collected));
close(fifoParent[1]);
}
else
{
char buf[100],collected[100];
close(fifoParent[1]);
close(fifoChild[0]);
in = 0;
cout<<"Enter a string: ";
gets(buf);
write(fifoChild[1],buf,sizeof(buf));
close(fifoChild[1]);
while(read(fifoParent[0],buf,1)>0)
{
collected[in] = buf[0];
in++;
}
collected[in] = 0;
cout<<"Read from Parent "<<collected<<endl;
}
return 0;
}
输出窗口如下所示:
Enter a string: abc // abc input given
Read from child abc
After reversing: cba
Read from parent cba
答案 0 :(得分:1)
通常,空管上的read
会阻塞,直到通过写入管道的写入端使数据可用为止。
因此,子进程在从父进程接收数据之前不能继续执行该行;它阻止等待它:
while(read(fifoChild[0],buf,1)>0)
一旦它读取了字符串,它就会唤醒它,将其反转并将其写回父节点。父进程到达下一行时也可能被阻塞,等待子进程写入反向字符串:
while(read(fifoParent[0],buf,1)>0)
read
的阻止行为类似于wait
或waitpid
的阻塞行为,但它等待数据到达文件描述符,而不是等待子进程改变状态。
通常,父和子进程同时执行 ,除非在系统调用中阻止其中一个或两个。
答案 1 :(得分:0)
当您调用fork()
时,会创建第二个进程,并且这两个进程都在代码中。判断您是新子进程还是原始父进程的唯一方法是查看fork()
的返回值。在documentation中,您可以看到如果fork()
返回0,则您处于子进程中。基本上,then
语句的if(ChildOrParentId==0)
块只在子进程中运行,而else
块只在父进程中运行。
如果你将这两个块视为不同的程序,其余的解释非常简单。父块请求一个字符串,将其发送给孩子,等待孩子发回一些东西,然后打印孩子发送的内容。同时,子块等待来自父节点的内容,打印它获取的内容,将其反转并打印出来,然后将反转的字符串发送回父节点。