Създайте дете с помощта на fork() вътре в цикъла for, за да стартирате execlp() с 2 канала, използвайки dup

Пиша C програма, която ще изпълнява Linux команди, като:

$ cat /etc/passwd | cut -f1 -d: | вид

докато чака детето да завърши, само едно дете завършва успешно. Кодът виси, показвайки "течащо сортиране"

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

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

  for(i=0; i< 3; 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 cat /etc/passwd\n");
    fflush(stdout);
    execlp("cat","cat","/etc/passwd", (char *)NULL);
    exit(EXIT_SUCCESS);

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

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

      }

    }
    else
    {
      listpid[i]=child;
    }

  }

  close(fd1[0]);
  close(fd1[1]);
  close(fd2[0]);
  close(fd2[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);

}

person user1863673    schedule 30.11.2012    source източник


Отговори (2)


Трябва да затворите тръбата fd1 в дете 2, в противен случай дете 1 ще виси в очакване на повече възможни входни данни.

Като друг проблем, вашият waitpid цикъл трябва да има условие за цикъл i < 3, а не i < 2.

person ecatmur    schedule 30.11.2012

Причината "зависва" е, че sort чака още вход. Няма да изведе нищо, докато входните тръби не бъдат затворени. Възможно има нещо нередно с каналите ви (трябва да проверите върнатите стойности от pipe и dup), но не виждам нищо.

Предполагам, че cut не е излязъл. Отново най-вероятната причина е, че входната му тръба не е затворена. И така, къде е отворено?

Няма да бъде отворен в процеса cat, защото няма причина да не е излязъл.

Той няма да бъде отворен в родителския процес, защото внимателно сте затворили всички дескриптори.

Той няма да бъде отворен в процеса cut, защото затваряте края за запис на fd1.

Това оставя самия процес sort: той все още има отворени дескриптори на fd1!

И така, sort увисва, защото чака cut да завърши, а cut увисва, защото чака sort, въпреки че sort никога няма да запише нищо във fd1.

Трябва или да затворите fd1 в третото дете, или трябва да уредите всяка тръба да съществува само в децата, които се нуждаят от тях.

Това все пак е моята теория.

person ams    schedule 30.11.2012