我尝试创建两个子进程并管道它们,但是第二个子进程没有对第一个生成ls的子进程生成的输出进行排序。我做错了什么?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int pipefd[2];
pid_t ls_pid, wc_pid;
pipe(pipefd);
if ((ls_pid = fork()) == 0) {
dup2(pipefd[1],STDOUT_FILENO);
close(pipefd[0]);
execl("/bin/ls", "ls", 0);
perror("exec ls failed");
exit(EXIT_FAILURE);
}
if ((wc_pid = fork()) == 0) {
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[1]);
execl("/usr/bin/sort", "sort", NULL);
perror("exec wc failed");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
答案 0 :(得分:1)
排序应该有效,但是你的代码中有2个警告,首先,确保在包含对fd的引用的所有进程中关闭fd,否则fd将不会关闭,这就是排序进程挂起的原因完成后,因为它没有从stdin收到EOF,这是因为父进程中的pipefd没有关闭。另一个是确保等待孩子退出并检查他们的退出状态。将以下内容添加到主函数的发送中:
close(pipefd[0]);
close(pipefd[1]);
int status;
int pid = waitpid(ls_pid, &status, 0);
pid = waitpid(wc_pid, &status, 0);
答案 1 :(得分:0)
您必须将NULL
作为第一个参数传递给execl
,就像在第二个参数中一样。会发生什么execl
正确执行(这就是你没有收到错误的原因)但是ls
命令不起作用,因为你给它一个无效的命令。
顺便说一句,您应该对所有操作系统请求进行错误控制,例如fork()
答案 2 :(得分:0)
结合所有评论并进行测试:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int pipefd[2];
pid_t ls_pid, wc_pid;
int status;
pipe(pipefd);
if ((ls_pid = fork()) == 0) {
dup2(pipefd[1],STDOUT_FILENO);
close(pipefd[0]);
close(pipefd[1]);
execlp("ls", "ls", NULL);
perror("exec ls failed");
exit(EXIT_FAILURE);
}
if ((wc_pid = fork()) == 0) {
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]);
close(pipefd[1]);
execlp("sort", "sort", NULL);
perror("exec sort failed");
exit(EXIT_FAILURE);
}
close (pipefd[0]);
close (pipefd[1]);
/* wait for two children to finish */
wait(&status);
wait(&status);
return EXIT_SUCCESS;
}