好的,所以我是一项关于管道的任务。目标是从命令行获取“深度”、“文件名”和“属性”。该文件是一个保存用户信息的txt文件,属性就是我们以后要根据哪些信息进行排序。然而,深度很重要,因为我需要根据用户输入的数字使用叉创建一个二叉树。深度为 1 时,我将拥有主进程、一个内部节点和 2 个叶节点。深度为 2 时,我将拥有我的主要进程,一个内部节点有两个内部节点作为子节点,它们每个都有两个叶节点作为子节点......等等。

我的代码目前将所有信息读入一个结构数组,创建正确数量的节点的二叉树,并且我的所有排序算法(Shell、Quick、Bubble)都可以工作。

现在,我必须实现命名管道并将数据向下传递到叶节点进行排序。每个内部节点都应该将数据拆分为它的子节点。然后,一旦数据到达叶节点,它们将实现不同的排序算法并将结果返回到它们的父节点/内部节点。内部节点将从它的两个子节点中获取排序后的数据并合并结果。最终,数据将一路合并回 anchor 节点。

我的问题是我根本无法将注意力集中在管道上。我不知道如何跟踪它们或在正确的时间初始化它们。我想通过给定的深度找出应该产生多少叶节点并以这种方式均匀地分割数据,然后只做一个 if 语句来对数据的每个部分运行正确的排序器,但这不会解决正确的问题问题。任何人都可以帮助我实现这一点,或者至少可以从什么开始?

树的创建看起来像这样

void forkTree(int size){
if(size == 0){
    return;
}
int left = fork();
if(left != 0){
    int right = fork();
        if(right == 0){
            sleep(1);
            forkTree(size-1);
        }
}
else{
    sleep(1);
    forkTree(size-1);
}

它是这样调用的
if(depth>0){
//initial fork
int anchor = fork();
//make binary tree only in child process
if(anchor==0){
    forkTree(depth);
}

最佳答案

查看有关 pipe 的文档。每个管道有两个末端,一个用于读取,一个用于写入。当您想将数据写入 child 然后读取结果时,每个 child 需要两个。如果你有一个二叉树,你在每个节点有两个 child 。所以它是四个管道和八个文件句柄,你在 parent 和 child 的一边关闭它们的一半。在父节点中,关闭管道的读取端以写入子节点,关闭管道的写入端以从子节点读取。在 child 身上,你做相反的事情。您可以查看手册页中的示例并根据您的任务进行调整。我建议您将用于 fork 一个 child 的代码分离到单独的函数中。您甚至可以在此函数中将数据写入子级,并仅返回管道的读取端。然后从两个 child 的两个管道中读取。不要忘记 wait 让两个 child 都能收割僵尸。

手册页中有示例:

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

int
main(int argc, char *argv[])
{
    int pipefd[2];
    pid_t cpid;
    char buf;
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <string>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (cpid == 0) {    /* Child reads from pipe */
        close(pipefd[1]);          /* Close unused write end */

        while (read(pipefd[0], &buf, 1) > 0)
            write(STDOUT_FILENO, &buf, 1);

        write(STDOUT_FILENO, "\n", 1);
        close(pipefd[0]);
        _exit(EXIT_SUCCESS);

    } else {            /* Parent writes argv[1] to pipe */
        close(pipefd[0]);          /* Close unused read end */
        write(pipefd[1], argv[1], strlen(argv[1]));
        close(pipefd[1]);          /* Reader will see EOF */
        wait(NULL);                /* Wait for child */
        exit(EXIT_SUCCESS);
    }
}

关于c - 需要帮助创建未知数量的命名管道来拆分和排序数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13182566/

10-15 15:01
查看更多