使用 fork() 从父进程和子进程计算的总和在 C 中不正确

Sum calculated from parent process and child process using fork() not correct in C

提问人:Ssq Dd 提问时间:11/18/2023 更新时间:11/18/2023 访问量:35

问:

我希望能得到一些关于以下问题的帮助。 因此,在子进程中,我得到的值为 7,该值在 for 循环之后确认了 printf 语句。 然而,问题在于,在将子进程的总和值写入父进程中partial_sum后,我收到不同的值 32_768。因此最后的结果不等于 13。

有人可以帮我找到代码中的问题吗? 提前致谢!

// question: what is the issue here???

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>

int main (int argc, char* argv[]) {
    int arr[] = {1, 2, 3, 4, 1, 2};
    int arr_size = sizeof(arr) / sizeof(int);
    int start, end;
    int pid = fork();
    int fd[2];
    if (pipe(fd) == -1) return 1;

    if (pid == 0){
        start = 0;
        end = arr_size / 2;
    } else {
        start = arr_size / 2;
        end = arr_size;
    }

    // calculation:
    int sum = 0;
    for (int i = start ; i < end; i++) {
        sum += arr[i];
    }
    printf("The sum is: %d\n", sum);

    // transferring the value;
    if (pid == 0) {
        close(fd[0]);
        if(write(fd[1], &sum, sizeof(sum)) == -1) return 1;
        close(fd[1]);
    } else {
        int partial_sum;
        close(fd[1]);
        if (read(fd[0], &partial_sum, sizeof(partial_sum)) == -1) return 2;
        close(fd[0]);
        int result = partial_sum + sum;
        printf("The final result is: %d", result);
        wait(NULL);
    }


}

预计结果是 13,但得到以下输出:

The sum is: 7
The sum is: 6
The final result is: 32774
Process finished with exit code 0
C 型管

评论

4赞 Ulrich Eckhardt 11/18/2023
你不应该以前吗?在任何情况下,在调试器中运行它都应该清楚地表明父级和子级之间的通信不起作用。pipe()fork()
0赞 Ian Abbott 11/18/2023
目前,父级和子级都创建自己的管道。尽管父级和子级中的管道将使用相同的文件描述符编号,但它们不是同一管道,因为它们具有不同的打开文件描述。没有任何东西写入父管道的“写入”端,也没有任何东西从子管道的“读取”端读取。
1赞 Jonathan Leffler 11/18/2023
请注意,读写的错误测试应该是 而不是 。您可以获得零字节读取,表示 EOF,短写入是一个问题。对于读取,您可能需要捕获变量中的值,以便区分错误和 EOF。!= sizeof(variable)== -1

答:

2赞 Eric Postpischil 11/18/2023 #1

当调用 after 时,它会在当前进程中打开一个单独的管道,因此您在父进程中得到一个管道,在子进程中得到另一个管道。pipefork

将呼叫移到 之前。这将创建一个管道,当复制进程时将共享该管道。pipeforkfork

此外,不要仅通过将值与 −1 进行比较来测试和返回值。它们可能会返回其他值,包括文件末尾的零或介于零和请求的字节数之间的数字。若要确定读取或写入是否完全成功,请将返回值与请求的字节数进行比较。(然后,如果您希望区分失败的情况,请执行进一步的比较。这样做会显示读取不起作用。readwrite