【问题标题】:Calculations in childs using pipes使用管道计算孩子
【发布时间】:2017-03-30 14:51:50
【问题描述】:

我的任务是

一个。一个父母和两个孩子

b.父级从用户那里获取数据

c。发送给孩子进行加减运算。

d。再次从用户那里获取输入并发送给另一个孩子进行乘法和除法。

e。第一个子进程创建另一个子 C3。

f。两个子进程都将结果发送到子进程 C3 以显示输出。

g.父进程在每个子进程任务完成后杀死该进程。

我写了下面的代码,但我不知道我做错了什么,我尝试调试它,但我不知道它有什么问题,它没有显示乘法和除法的结果。

这是我的代码:

#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

它给了我以下输出:

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

如果有人能帮上忙,非常感谢。

【问题讨论】:

  • 这里有三个fork() 调用。你还是说:“一个父母和两个孩子”?
  • 第一个子进程创建另一个子 C3。第三个叉子。
  • 我不认为它解释了你观察到的行为,但主进程分叉了两个孩子然后wait()s 只为一个。
  • 如何让它等待所有人?
  • @MohammadTayyab,一种方法是在您标记为“else2”的else 块末尾添加另一个对wait() 的调用。

标签: c linux pipe fork


【解决方案1】:

您可以这样做:

#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;
}

希望对你有帮助:)

【讨论】:

  • 谢谢!它有效,但你能解释一下吗?我哪里做错了?
【解决方案2】:

问题很可能是孙子消耗了一个打算由子 2 读取的数据作为其输入。 Child 2 然后挂起尝试从管道读取,因为它本身是唯一剩下的向该管道写入任何内容的进程,并且在完成读取之前它不能这样做。这可能是因为所有三个子进程都从相同的两个管道读取输入,而进程之间没有任何(其他)同步。

总体而言,您的策略值得怀疑。将每个管道末端指定为仅由一个进程使用,从而指定每个完整的管道用于恰好一对进程之间的通信,会更加安全和稳健。切换到这种策略需要相同数量的管道,但使用模式不同:

  • 在管道 0 上,父级将两个输入一个接一个地发送给子级 1
  • 在管道 1 上,父级将两个输入一个接一个地发送给子级 2
  • 在管道 2 上,子 1 将其结果一个接一个地发送给孙子/子 3
  • 在管道 3 上,子 2 将其结果一个接一个地发送给孙子/子 3

这样,其中一个进程就不会错误地使用本应用于另一个进程的数据,或者错误的来源以及发送给它的任何数据的含义。

【讨论】:

  • 问题是为什么它在计算孙子中的 sum 和 sub 后没有执行,我尝试了你给定的解决方案,通过在管道 03 上写入子 2 结果并按照你所说的通过管道 03 读取孙子,但它也给了我相同的输出。只显示加减法。
  • @MohammadTayyab:该解决方案确实有效。我正在测试它,但约翰的回答比我快。
  • 如果这行得通!你能用代码编辑答案吗,因为我可能不太理解,我试过这个,但不适合我。
  • @MohammadTayyab,不,我不会为你写/修改你的作业。但是,请仔细阅读我的答案。它需要更多的更改,而不仅仅是更改写入和读取的 FD。另请注意,我的编号从 0 开始(但无论如何只是一个示例),而您的编号从 1 开始。
  • 我知道你是怎么数的,我试过了。 @JohnBollinger
【解决方案3】:

您似乎误解了管道的工作原理。您所有的子进程都共享相同的管道。当孩子 1 从pfds[0] 读取数据时,这意味着当孩子 2 尝试从中读取数据时,数据已经消失了。或者也许孩子 2 先读取数据而孩子 1 没有。无论哪种方式,只有 1 个孩子可以读取数据。

您应该创建每个管道仅用于一种用途 - 即让父母与孩子 1 交谈。

也许创建一个函数来创建一个管道并派生一个子进程,您可以根据需要重新使用它,类似于以下内容。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多