管道两个子进程,一个用于ls,另一个用于排序,但排序不起作用

时间:2016-04-12 23:31:25

标签: c sorting unix piping

我尝试创建两个子进程并管道它们,但是第二个子进程没有对第一个生成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;
}

3 个答案:

答案 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;
}