J'ai deux programmes simples: A
et B
. A
s'exécuterait en premier, puis B
obtient la «stdout» de A
et l'utilise comme son «stdin». Supposons que j'utilise un système d'exploitation GNU / Linux et la manière la plus simple de le faire serait:
./A | ./B
Si je devais décrire cette commande, je dirais que c'est une commande qui prend l'entrée (c'est-à-dire la lecture) d'un producteur ( A
) et écrit sur un consommateur ( B
). Est-ce une description correcte? Suis-je en train de manquer quelque chose?
pipe
terminology
nihulus
la source
la source
Réponses:
La seule chose à votre question qui se démarque comme erronée est que vous dites
En fait, les deux programmes seraient lancés à peu près en même temps. S'il n'y a pas d'entrée pour
B
quand il essaie de lire, il se bloquera jusqu'à ce qu'il y ait une entrée à lire. De même, s'il n'y a personne qui lit la sortieA
, ses écritures seront bloquées jusqu'à ce que sa sortie soit lue (une partie sera tamponnée par le tube).La seule chose qui synchronise les processus qui participent à un pipeline est les E / S, c'est-à-dire la lecture et l'écriture à travers le tuyau. Si aucune écriture ou lecture ne se produit, les deux processus s'exécuteront de manière totalement indépendante l'un de l'autre. Si l'un ignore la lecture ou l'écriture de l'autre, le processus ignoré se bloquera et finira par être tué par un
SIGPIPE
signal (s'il écrit) ou obtiendra une condition de fin de fichier sur son flux d'entrée standard (si la lecture) lorsque l'autre processus se termine .La façon idiomatique de décrire
A | B
est qu'il s'agit d'un pipeline contenant deux programmes. La sortie produite sur la sortie standard du premier programme est disponible pour être lue sur l'entrée standard par le second ("[la sortie de]A
est canalisée dans [l'entrée de]B
"). La coque fait la plomberie requise pour permettre que cela se produise.Si vous voulez utiliser les mots «consommateur» et «producteur», je suppose que ça va aussi.
Le fait qu'il s'agisse de programmes écrits en C n'est pas pertinent. Le fait qu'il s'agisse de Linux, macOS, OpenBSD ou AIX n'est pas pertinent.
la source
mkfifo
pour créer un canal nommé, puis démarrez B en arrière-plan en lisant le canal, puis A en y écrivant. Il s'agit cependant de choix, car l' effet serait le même.yes | sed 10q
Le terme habituellement utilisé dans la documentation est "pipeline", qui consiste en une ou plusieurs commandes, voir la définition POSIX Donc, techniquement parlant, c'est deux commandes que vous avez là, deux sous-processus pour le shell (soit
fork()+exec()
des commandes externes éditées ou des sous-shell)Quant à la partie producteur-consommateur , le pipeline peut être décrit par ce schéma, car:
/proc/<pid>/fd
répertoire).stdout
et les consommateurs lisentstdin
comme s'il s'agissait d'une seule commande en cours d'exécution, c'est-à-dire qu'ils peuvent exister les uns sans les autres .La différence que je vois ici est que, contrairement à Producer-Consumer dans d'autres langues, les commandes shell utilisent la mise en mémoire tampon et écrivent stdout une fois que la mémoire tampon est remplie, mais il n'y a aucune mention que Producer-Consumer doit suivre cette règle - n'attendez que lorsque la file d'attente est remplie ou jetée les données (ce qui est autre chose que le pipeline ne fait pas).
la source