这里发生父进程和子进程的切换?
问题描述:
代码实际做的是从父进程获取输入,并通过管道将其发送给子进程。子进程将其反转,然后通过另一个管道将其发送回父进程。代码中没有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
答
通常,read
在一个空的管块直到数据可通过写入写入结束的管道。
因此,子进程无法继续执行此线,直到它从父进程接收数据;它会阻止等待它:
while(read(fifoChild[0],buf,1)>0)
一旦它读取的字符串,它唤醒,逆转它,并将其写回父。家长也可能会当它达到以下行,等待子进程写颠倒字符串阻止:
while(read(fifoParent[0],buf,1)>0)
的read
阻塞行为类似于wait
或waitpid
阻塞的行为,但它等待使数据到达文件描述符,而不是等待子进程改变状态。
一般来说,父级和子级进程同时执行,除非系统调用中一个或两个进程被阻止。
答
当您拨打fork()
时,会创建第二个进程,并且这两个进程都位于代码中的此位置。判断您是新的子进程还是原始父进程的唯一方法是查看返回值fork()
。在documentation中,您可以看到如果fork()
返回0,那么您处于子进程中。所以基本上,if(ChildOrParentId==0)
语句的then
块只能在子进程中运行,而else
块只能在父进程中运行。
如果您将这两个块视为不同的程序,其余解释非常简单。父块要求输入一个字符串,将其发送给孩子,等待孩子发回一些东西,然后打印孩子发送的内容。同时,子块等待来自父项的东西,打印它得到的内容,将其反转并打印出来,然后将反转的字符串发送回父项。
你是什么意思的“他们如何工作”? – 2014-09-01 18:45:04
这是“工作”,因为这是管道所做的 - 你为一端写了一些东西,然后从另一端读取它。你在问管道是如何工作的?或者子进程如何继承文件描述符?或者是其他东西? – 2014-09-01 18:46:23
询问“从孩子abc读取”如何执行?上面给出的输出是通过在父进程和子进程之间来回切换产生的......对吧?哪些陈述导致了这一点? – 2014-09-01 18:49:22