Calculations in childs using pipes

为君一笑 提交于 2020-01-05 09:28:08

问题


My task is

a. A parent and two childs

b. Parent take data from the user

c. Send to a child for addition and subtraction.

d. Again take input from user and send to another child for multiplication and division.

e. First child process creates another child C3.

f. Both the childs send result to the child process C3 to show output.

g. Parent process after completion of each child process task kill the process.

I've write the following code but i don't know where I'm doing wrong, I tried to debug it but I do not know what is wrong with it, it not showing the multiplication and division result.

Here is my code:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include<string.h>
#include <stdlib.h>

int main()
{
    int status = 0;
    int pfds[2];
    int pfds2[2];
    int pfds3[2];
    int pfds4[2];
    int val = 0;
    int val2 = 0;
    pipe(pfds);
    pipe(pfds2);
    pipe(pfds3);
    pipe(pfds4);
    printf("Enter FIRST Number:  ");
    scanf("%i", &val);
    printf("Enter SECOND Number:  ");
    scanf("%i", &val2);
    if (fork() == 0)
    {
//Child
        printf("I'm Child 1 and I'm Calculating Sum AND Differnece Of Numbers\n");
        read(pfds[0], &val, sizeof(val));
        read(pfds2[0], &val2, sizeof(val));
        int sum = val + val2;
        int sub = val - val2;
        write(pfds3[1], &sum, sizeof(val));
        write(pfds4[1], &sub, sizeof(val));
        if (fork() == 0)
        {
            read(pfds3[0], &val, sizeof(val));
            printf("Sum Of Numbers Is : %i\n", val);
            read(pfds4[0], &val, sizeof(val));
            printf("Sub Of Numbers Is : %i\n", val);
            read(pfds[0], &val, sizeof(val));
            printf("Mul Of Numbers Is : %i\n", val);
            read(pfds2[0], &val, sizeof(val));
            printf("Div Of Numbers Is : %i\n", val);
            exit(1);
        }
        else
        {
            wait(&status);
        }
        exit(1);
    }
    else
    {
        if (fork() == 0)
        {
//Child2
            printf("I'm Child 2 and I'm Calculating Multiplication and Division Of Number\n");
            read(pfds[0], &val, sizeof(val));
            read(pfds2[0], &val2, sizeof(val));
            int mul = val * val2;
            int div = val / val2;
            write(pfds[1], &mul, sizeof(val));
            write(pfds2[1], &div, sizeof(val));
            exit(0);
        }
        else
        {
//wait(&status);
            write(pfds[1], &val, sizeof(val));
            write(pfds2[1], &val2, sizeof(val));
            wait(&status);
        } //else1
    } //else2
} //main

It's giving me the following output:

Enter FIRST Number:  4
Enter SECOND Number:  2
I'm Child 1 and I'm Calculating Sum AND Differnece Of Numbers
I'm Child 2 and I'm Calculating Multiplication and Division Of Number
Sum Of Numbers Is : 6
Sub Of Numbers Is : 2

If someone can help thankyou very much.


回答1:


Here is what you can do:

#include <stdio.h>
#include <unistd.h>
#include<stdlib.h>
int main()
{
int status = 0;
int fd1[2], fd2[2], fd3[2], fd4[2], a, b;
pipe(fd1); pipe(fd2);
pipe(fd3); pipe(fd4);
printf("Input two numbers for + and - ");
scanf("%d,", &a); scanf("%d,", &b);
write(fd1[1], &a, sizeof(int));
write(fd2[1], &b, sizeof(int));
printf("Input two numbers for multiplication and division\n");
scanf("%d,", &a); scanf("%d,", &b);
write(fd3[1], &a, sizeof(int));
write(fd4[1], &b, sizeof(int));
pid_t child1 = fork();
if (child1 == 0)
{
    int status = 0, a, b, c;
    read(fd1[0], &a, sizeof(int));
    read(fd2[0], &b, sizeof(int));
    printf("I'm 1st child and calculating + and -\n");
    c = a + b;
    a = a - b;
    write(fd1[1], &c, sizeof(int));
    write(fd2[1], &a, sizeof(int));
    pid_t c3 = fork();
    if (c3 == 0)
    {
        int sum, sub, mul, div;
        read(fd1[0], &sum, sizeof(int));
        read(fd2[0], &sub, sizeof(int));
        read(fd3[0], &mul, sizeof(int));
        read(fd4[0], &div, sizeof(int));
        printf("SUM = %d\n", sum);
        printf("SUB = %d\n", sub);
        printf("MUL = %d\n", mul);
        printf("DIV = %d\n", div);
    }
}
else
{
    pid_t child2 = fork();
    if (child2 == 0) {
        int status = 0, a, b, c;
        read(fd3[0], &a, sizeof(int));
        read(fd4[0], &b, sizeof(int));
        printf("I'm 2nd child and calculating multiplication and division");
        c = a*b;
        a = a / b;
        write(fd3[1], &c, sizeof(int));
        write(fd4[1], &a, sizeof(int));
    }
}
return 0;
}

Hope this will help you :)




回答2:


The problem is likely that the grandchild consumes one of the data meant to be read by child 2 as its input. Child 2 then hangs trying to read from the pipe, because it itself is the only processes left to write anything to that pipe, and it cannot do so until it has finished its read. This can happen because all three children read inputs from the same two pipes, without any (other) synchronization between processes.

Overall, your strategy is dubious. It is much safer and more robust to designate each pipe end for use by exactly one process, and thus to designate each whole pipe for communication between exactly one pair of processes. Switching to this strategy would require the same number of pipes, but a different pattern of usage:

  • on pipe 0, the parent sends the two inputs to child 1, one after the other
  • on pipe 1, the parent sends the two inputs to child 2, one after the other
  • on pipe 2, child 1 sends its results to the grandchild / child 3, one after the other
  • on pipe 3, child 2 sends its results to the grandchild / child 3, one after the other

That way, there is no possibility of one of the processes mistakenly consuming data meant for a different one, or to mistake the source and therefore the meaning of any of the data sent to it.




回答3:


The problem looks like you've misunderstood how pipes work. All your child processes are sharing the same pipes. When child 1 reads from pfds[0] that means that when child 2 tries reading from it, the data is already gone. Or maybe child 2 reads the data first and child 1 goes without. Either way, only 1 child can read the data.

You should create each pipe for one use only - ie for parent to talk to child 1.

Maybe create a function that creates a pipe and forks a child process that you can re-use as required, something along the lines of.

pid_t create_child(int *pipefds[2])
  {
  pipe(*pipefds);
  return fork();
  }


来源:https://stackoverflow.com/questions/43121331/calculations-in-childs-using-pipes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!