Pipes UNIX Entre les Processus Enfants
Je suis en train d'écrire un programme qui va générer un nombre arbitraire de processus enfants et les tuyaux entre eux, semblable à une ligne de commande du pipeline. Dans mon cas, je suis en train de faire "ls-l | more" et que la sortie vers stdout, alors le parent poursuivre l'exécution d'autres commandes.
J'ai le code suivant comme un exemple minimal:
int main (int argc, const char * argv[]) {
int fd[2];
pipe(fd);
chdir("/directory/with/lots/of/files");
//Create one child process for more
int pid = fork();
if (pid == 0) {
close(fd[1]);
int ret = dup2(fd[0],0);
if (ret < 0) perror("dup2");
char *argv[10];
argv[0] = "more"; argv[1] = NULL;
execvp("more", argv);
}
//Create another child process for ls
int pid2 = fork();
if (pid2 == 0) {
int ret = dup2(fd[1],1);
if (ret < 0) perror("dup2");
char *argv[10];
argv[0] = "ls"; argv[1] = "-l";
argv[2] = NULL;
execvp("ls", argv);
}
//wait for the more process to finish
int status;
waitpid(pid, &status, 0);
printf("Done!\n");
return 0;
}
Maintenant, quand j'exécute le programme (enfermé dans une fonction main() de cours) j'arrive à la fin avec est plus, ce qui est prévu. Je vais appuyez sur "d" à la page en baisse de plus de sortie et "u" pour aller vers le haut, et il semble bien fonctionner. Mais quand j'arrive en bas, au lieu de sortir comme de plus, il laisse une ligne vide. Ctrl-C pour quitter, mais il sort de l'ensemble du programme, qui signifie "le Fait!" la ligne n'est jamais imprimé. Un film est disponible ici qui illustre ce qui se passe (notez qu'à la fin, je vous appuyez sur Ctrl-C pour revenir à bash).
Des idées sur ce point? Je suis juste essayer de comprendre comment le changer pour le où, au lieu d'aller à une ligne vide après plus atteint le fond, plus ferme et renvoie au processus parent de sorte qu'il peut poursuivre l'exécution.
more
est un lien symbolique vers less
. Moins de besoins -e
à quitter à la fin du fichier. Il est possible qu'il y a une différence dans la PATH
dans votre environnement du programme par rapport à votre environnement interactif.Il n'est pas, mais merci pour le heads up. Qui me donne juste un plus de cas de test. 🙂
OriginalL'auteur Justin Mrkva | 2011-02-20
Vous devez vous connecter pour publier un commentaire.
Vous devez
close()
au moins l'écriture à la fin de votre tuyau, sinonmore
ne verrez jamais des expressions du FOLKLORE. Par exemple:Vous devez également
close(fd[0])
après ladup2()
dans le premier enfant, et de même pour lafd[1]
dans le deuxième enfant.Bingo, cela a fonctionné! Je ferme les tuyaux dans le processus enfants (au moins dans la version finale, je viens de réaliser que l'exemple minimal manque un
close(fd[0]);
dans le deuxième enfant), mais je n'ai jamais pensé à les fermer sur le parent. Après avoir cherché un peu plus loin j'ai trouvé le commentaire "Après la fourche, vous aurez un seul tuyau avec deux entrées et deux sorties" qui fait sens dans ce contexte. Merci! EDIT: Yep, la caf, j'ai repéré que j'allais sur elle, mais je ne les fermer dans la version de production. 🙂OriginalL'auteur Robie Basak
Je pense que c'est à cause de la
wait() function
. Suivant la logique, votre deuxième enfant, processus de sorties pour le premier enfant de processus, signifiant la fin de la première que la seconde.Dans votre
wait
de la fonction vous êtes en attente pour le premier processus à la fin, mais vous n'êtes pas d'attente pour le deuxième processus. Cela signifie que si le deuxième processus est de ne pas envoyer un EOF à la sortie jamais, votre premier processus n'aura pas de fin, je suppose.Vous pouvez essayer d'attendre le deuxième processus, au lieu de la première et de vérifier si c'est bien le problème.
OriginalL'auteur Tiago