管道、Fork和Exec-父进程和子进程之间的双向通信

管道、Fork和Exec-父进程和子进程之间的双向通信,c,exec,fork,pipe,C,Exec,Fork,Pipe,我的操作系统类中的赋值要求我通过递归调用同一程序上的exec来构建二元进程树。目标是将一些任意任务拆分为单独的进程。父级应与子级通信,子级仅通过未命名管道与父级通信。其思想是,父级将工作的一半发送给每个子级,并递归进行,直到满足基本情况,即传递给每个子级的字符串长度为时,argv2中的第一个条目应该是可执行文件的名称(就像传入的argv[0]) char *argv2[] = {"two_way_pipes", "some random arg...", NULL}; execvp("two_w

我的操作系统类中的赋值要求我通过递归调用同一程序上的exec来构建二元进程树。目标是将一些任意任务拆分为单独的进程。父级应与子级通信,子级仅通过未命名管道与父级通信。其思想是,父级将工作的一半发送给每个子级,并递归进行,直到满足基本情况,即传递给每个子级的字符串长度为时,
argv2
中的第一个条目应该是可执行文件的名称(就像传入的
argv[0]

char *argv2[] = {"two_way_pipes", "some random arg...", NULL};
execvp("two_way_pipes", argv2);
从:

execv()
execvp()
execvpe()
函数提供指向以null结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。按照惯例,第一个参数应指向与正在执行的文件关联的文件名。指针数组必须以null指针结尾

除此之外,调用
execv()
很可能失败

要测试这一点,请修改这些行

execvp("two_way_pipes", argv2);
_exit(0);
将来

要修复此更改

execvp("two_way_pipes", argv2);
将来


此外,如果子项未执行exec*()ed,则此行

read(PARENT_READ, buff, 4); // should read "test" which was written by the child to stdout
失败,而
buff
未初始化,因此此行

fprintf(stderr, "in parent | message received: %s\n", buff);  
引起未定义的行为

要解决此问题,请至少通过更改

char buff[5];
将来


正如Jonathon Reinhart所说,你应该改变这句话:

char *argv2[] = {"some random arg to make sure that argc == 2 in the child", NULL};
execvp("two_way_pipes", argv2);
致:

然后,它会按预期工作:

echo test | ./two_way_pipes
in parent | message received: test

在您的程序中,您编写了“双向管道”,但它不在您的路径中,因此您确实需要额外的路径。/so argv[0]则是(“./two\u-way\u-pipes”)。

谢谢Jonathan。我根据您的答案修改了argv2,但家长仍然无法从被执行的孩子那里获取数据。您的exevp成功了吗?尝试用
perror(“exevp”)替换退出(0))
谢谢William。我将_exit(0)调用替换为peror(“execvp”)。该错误消息从未打印出来,但我开始调整我的exec调用,并出于某种原因将调用更改为execl(“双向管道”,“双向管道”,“1”,NULL);修复了此问题。此代码因此无法测试系统调用的结果。不这样做会使测试和调试变得困难,程序也会变得脆弱。请参阅我的答案。这真的不是什么大问题,因为它一直都在发生-但令人印象深刻的是,人们会经常拼错某人的名字-即使是在几百像素之外同一页。很抱歉。我怀疑如果我被命名为Anthany,人们也会经常拼错:-)
execvp("./two_way_pipes", argv2);
read(PARENT_READ, buff, 4); // should read "test" which was written by the child to stdout
fprintf(stderr, "in parent | message received: %s\n", buff);  
char buff[5];
char buff[5] = "";
char *argv2[] = {"some random arg to make sure that argc == 2 in the child", NULL};
execvp("two_way_pipes", argv2);
char *argv2[] = {argv[0], "some random arg...", NULL};
execvp(argv[0], argv2);
echo test | ./two_way_pipes
in parent | message received: test