4

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

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

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

我的问题是我根本无法将注意力集中在管道上。我不知道如何跟踪它们或在正确的时间初始化它们。我想过找出给定的深度应该产生多少叶节点并以这种方式均匀地分割数据,然后只做一个 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);
}
4

1 回答 1

0

查看有关文档pipe. 每个管道有两端,一端用于读取,一端用于写入。当您想将数据写入孩子然后读取结果时,每个孩子需要两个。如果你有一个二叉树,那么每个节点都有两个孩子。所以它是四个管道和八个文件句柄,您可以在父母和孩子的一侧关闭其中的一半。在父节点中,关闭管道的读取端以写入子节点,关闭管道的写入端以从子节点读取。在孩子身上,你做的恰恰相反。您可以查看手册页中的示例并适应您的任务。我建议您将用于将一个孩子分叉的代码分离到单独的函数中。您甚至可以在此函数中将数据写入子级,并仅返回管道的读取端。然后从两个孩子的两个管道中读取。不要忘记wait让两个孩子都收获僵尸。

手册页中有一个示例:

#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);
    }
}
于 2015-03-18T10:52:02.800 回答