好的,所以我是一个完全停留在管道上的任务。目标是从命令行获取“深度”“文件名”和“属性”。该文件是一个保存用户信息的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);
}
答案 0 :(得分: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);
}
}