使用fork()在for循环中创建子进程运行execlp()

时间:2012-11-29 21:32:09

标签: c linux for-loop exec fork

我正在编写一个运行Linux命令的C程序,如:

  

$ cat / etc / passwd | cut -f1 -d:|排序

这个想法是使用fork()创建子进程以使用execlp()运行命令。我计划使用两个管道进行通信,并使用dup()指示输入输出。

输出错误:

  

ls -l | wc -c on命令返回1746   该计划返回1761

代码(编辑以反映建议):

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>

int main()
{
  int i,fd1[2],status,listpid[2];
  pid_t child;
  pipe(fd1);

  for(i=0; i< 2; i++)
  {
    printf("\ncreating child\n");
    if((child = fork()) == -1)
    {
      perror("fork");
      exit(EXIT_FAILURE);

    }
    else if(child == 0)
    {
      if(i == 0)
      {
    close(1); dup(fd1[1]);
    close(fd1[0]);
    close(fd1[1]);
    printf("\nrunning ls -l\n");
    fflush(stdout);
    execlp("ls","ls","-l", (char *)NULL);
    exit(EXIT_SUCCESS);

      }
      else if(i == 1)
      {
    close(0); dup(fd1[0]);
    close(fd1[1]);
    close(fd1[0]);
    printf("\nrunning wc -c\n");
    fflush(stdout);
    execlp("wc","wc","-c", (char *)NULL);
    exit(EXIT_SUCCESS);

      }

    }
    else
    {
      listpid[i]=child;
    }

  }

  close(fd1[0]);
  close(fd1[1]);

  for(i = 0; i < 2; i++) 
  {
    waitpid(listpid[i], &status, 0);

    if(WIFEXITED(status)) 
    {
      printf("\n[%d] TERMINATED (Status: %d)\n",listpid[i], WEXITSTATUS(status));

    }

  }
  exit(EXIT_SUCCESS);

}

2 个答案:

答案 0 :(得分:1)

首先你不能在循环中等待 - 如果ls的输出足够大,它会填满管道,所以直到有人读取它才会完成:你必须在for循环之后等待两个孩子。 第二 - 只要管道的另一端打开,wc就会继续,即你必须关闭父管道。

答案 1 :(得分:0)

更新后,两个子进程的行为正常。但是,您仍需要添加:

close(fd1[0]);
close(fd1[1]);

在启动子项的for循环和收集退出状态的for循环之间。

由于管道的写入端仍处于打开状态,wc未收到EOF,因此它不会终止,因此您的进程无限期地等待。