在哪里切换父进程和子进程?

时间:2014-09-01 18:42:57

标签: c++ process pipe

代码实际上做的是从父进程获取输入,通过管道将其发送到子进程。子进程将其反转,然后通过另一个管道将其发送回父级。代码中没有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

2 个答案:

答案 0 :(得分:1)

通常,空管上的read会阻塞,直到通过写入管道的写入端使数据可用为止。

因此,子进程在从父进程接收数据之前不能继续执行该行;它阻止等待它:

    while(read(fifoChild[0],buf,1)>0)

一旦它读取了字符串,它就会唤醒它,将其反转并将其写回父节点。父进程到达下一行时也可能被阻塞,等待子进程写入反向字符串:

    while(read(fifoParent[0],buf,1)>0)

read的阻止行为类似于waitwaitpid的阻塞行为,但它等待数据到达文件描述符,而不是等待子进程改变状态。

通常,父和子进程同时执行 ,除非在系统调用中阻止其中一个或两个。

答案 1 :(得分:0)

当您调用fork()时,会创建第二个进程,并且这两个进程都在代码中。判断您是新子进程还是原始父进程的唯一方法是查看fork()的返回值。在documentation中,您可以看到如果fork()返回0,则您处于子进程中。基本上,then语句的if(ChildOrParentId==0)块只在子进程中运行,而else块只在父进程中运行。

如果你将这两个块视为不同的程序,其余的解释非常简单。父块请求一个字符串,将其发送给孩子,等待孩子发回一些东西,然后打印孩子发送的内容。同时,子块等待来自父节点的内容,打印它获取的内容,将其反转并打印出来,然后将反转的字符串发送回父节点。