0

次のような Linux コマンドを実行する C プログラムを作成しています。

$ 猫 /etc/passwd | カット -f1 -d: | 選別

アイデアは、fork() を使用して子プロセスを作成し、execlp() を使用してコマンドを実行することです。通信に 2 つのパイプを使用し、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);

}
4

2 に答える 2

1

まず、ループで待機することはできません。lsの出力が十分に大きい場合、パイプがいっぱいになるため、誰かがそれを読み取るまで終了しません。forループの後で両方の子を待つ必要があります。2番目-パイプのもう一方の端が開いている限り、wcは続行されます。つまり、親のパイプも閉じる必要があります。

于 2012-11-29T21:51:23.947 に答える
0

更新後、2つの子プロセスは正しく動作しています。ただし、次を追加する必要があります。

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

for子を起動するforループと終了ステータスを収集するループの間。

パイプの書き込み端はまだ開いているため、wcEOFを受信しないため、終了しません。したがって、プロセスは無期限に待機しています。

于 2012-11-30T07:06:32.643 に答える