Quelle est l'ingéniosité exacte des pipes Unix

52

J'ai entendu l'histoire de la façon dont Douglas McLlroy a proposé le concept et de la façon dont Ken Thompson l'a mis en œuvre en une nuit.

Autant que je sache, pipe est un appel système qui partage une partie de la mémoire entre deux processus, l'un écrit et l'autre lisant.

En tant que personne qui ne connaît pas bien les concepts internes ou les concepts internes d'un système d'exploitation, je me demandais quel était exactement le "génie" de l'histoire. Est-ce l'idée de deux processus partageant la mémoire? Ou est-ce la mise en œuvre? Ou les deux?

PS: Je suis conscient de l’utilité du tuyau ou de son utilisation en coque. La question concerne le concept et la mise en œuvre de la|

aoak
la source
4
Je suppose qu'à ses débuts, il était assez radical de faire pression pour la mise en place d'un mécanisme permettant de composer des applications. Pour ce faire, vous devez avoir une conception bien formée de la séparation entre interface et implémentation, et prendre conscience de l’utilité de la composition fonctionnelle en programmation.
Chan-Ho Suh
4
De plus, les applications en cours d’exécution disposaient déjà d’un descripteur d’entrée standard et d’un descripteur de sortie standard, et les API du système d’exploitation de type Unix disposaient de fonctions de lecture / écriture à appliquer à ces descripteurs. L'utilisation intelligente de quelques concepts orthogonaux et hautement performants (poignées, sorties et entrées) conduit non seulement à des tuyaux, mais également à des sockets, des interactions caractère-périphérique et des dizaines d'autres choses. Alors, maintenant que nous avons des descripteurs de fichier (pour le terminal qui fournit une entrée au clavier et une sortie texte), composons les applications de sorte qu'une application devienne le terminal de l'autre.
Warren P
6
@WarrenP En fait, Unix a obtenu une entrée et une sortie standard à cause de l' pipe()appel système et de l' |opérateur shell (ref: McIlroy ). Ou, comme Voltaire aurait pu le dire, " Si [stdio] n'existait pas, il serait nécessaire de l'inventer " :-)
Ross Patterson
Il n’existait pas de poignées de fichiers ni de poignées d’entrée et de sortie jusqu’à AFTER pipes?
Warren P
4
@WarrenP: Cela ressemble à ce que Patterson dit: voici d'abord les descripteurs de fichiers. Ensuite, ces gars ont eu l’idée que chaque programme contenait par défaut un descripteur d’entrée et un descripteur de sortie, ce qui permettait ensuite aux programmes de chaîner de manière triviale. Celles-ci sont connues sous le nom d'entrées / sorties "standard".
Mooing Duck

Réponses:

109

Autant que je sache, pipe est un appel système qui partage une partie de la mémoire entre deux processus, l'un écrit et l'autre lisant.

En réalité, il n'y a pas de mémoire partagée impliquée. Le lecteur et l'écrivain ne partagent aucune partie de leur espace d'adressage et n'utilisent aucune synchronisation explicite.

Les processus de lecture et d'écriture font readet les writeappels système exactement comme ils le feraient s'ils lisaient / écrivaient dans un fichier. C’est le génie… l’innovation: l’idée que la communication (simple) entre processus et les E / S sur fichier peuvent être gérées de la même manière… du point de vue du programmeur d’application et de l’utilisateur.

Une fois le canal configuré, le système d'exploitation (et non le code de l'application ou les bibliothèques dans l'espace utilisateur) se charge de la mise en mémoire tampon et de la coordination. En toute transparence.


En revanche, avant l’invention du concept de canal, si vous deviez effectuer un traitement "pipeline", vous auriez généralement une sortie d’écriture d’application dans un fichier, puis, une fois terminé, vous exécuteriez la deuxième application pour lire à partir du fichier. fichier.

Si vous vouliez un véritable pipeline, vous pouvez également coder les deux applications pour qu'elles configurent un segment (réel) de mémoire partagée et utilisent des sémaphores (ou autre chose) pour coordonner la lecture / écriture. Compliqué ... et en conséquence pas souvent fait.

Stephen C
la source
34
"C’est le génie ... l’innovation: la notion selon laquelle la communication interprocessus et les E / S sur fichier peuvent être gérées de la même manière" - exactement cela. Il vous permet d’avoir une communication interprocessus entre des programmes qui n’ont jamais été conçus, et ne sait même pas (ce qui est nécessaire) ce qui se passe.
Guntram Blohm soutient Monica
6
Il est également utile de noter que l'utilisation d'E / S sur fichier pour IPC était principalement utile, car Unix était conçu pour le traitement de texte - la transmission en continu de données texte d'un programme à l'autre, permettant une composition relativement simple, ce qui permettait de construire l'ensemble du système. relativement simples, de petits programmes qui transmettaient des données d’un flux à un autre en (éventuellement) de longues chaînes d’opérations simples. En gros, cela signifiait que vous disposiez d'un langage relativement flexible pour gérer le traitement de texte.
Luaan 12/12
1
Ainsi, "l'ingéniosité du pipe Unix" est "l'ingéniosité d'Unix": toutes les entrées / sorties (y compris la communication interprocessus, les fichiers standard et le reste des objets du système de fichiers) sont gérées comme des fichiers.
Mark Hurd
Un autre coup de génie fut qu'UNIX préconisait des structures de fichiers lisibles par l'homme à une époque où chaque octet comptait ...
EvertW
14

À mon avis, le génie de l'idée de "pipes" est la simplicité d'utilisation.

Vous n'avez pas à faire d'appels système, à allouer de la mémoire, rien de compliqué. Dans le shell, vous utilisez un seul caractère: |. Cela donne un pouvoir extraordinaire dans la combinaison d'outils simples (ou complexes) pour une tâche donnée.

Effectuez certaines tâches quotidiennes courantes, telles que le tri ordonné du texte. Vous pouvez avoir une commande qui répertorie tout un tas de noms. (Pour mon exemple, j'utiliserai un fichier contenant une multitude de noms, avec l'aimable autorisation de listofrandomnames.com.) À l'aide des tuyaux, vous pouvez effectuer les opérations suivantes:

$ cat names.txt
Sally Weikel
Dana Penaflor
Christine Hook
Shaneka Flythe
Almeda Crook
Freddie Lindley
Hester Kersh
Wanda Ruse
Megan Mauzy
Samuel Mancha
Paris Phipps
Annika Accardo
Elena Nabors
Caroline Foti
Jude Nesby
Chase Gordy
Carmela Driggers
Marlin Ostendorf
Harrison Dauber
$ cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100
Accardo, Annika     Hook, Christine     Ostendorf, Marlin
Crook, Almeda       Kersh, Hester       Penaflor, Dana
Dauber, Harrison    Lindley, Freddie    Phipps, Paris
Driggers, Carmela   Mancha, Samuel      Ruse, Wanda
Flythe, Shaneka     Mauzy, Megan        Weikel, Sally
Foti, Caroline      Nabors, Elena
Gordy, Chase        Nesby, Jude

Ceci n'est qu'un exemple. il y en a des milliers. Pour quelques autres tâches spécifiques qui sont remarquablement facilitées par l’utilisation de pipes, voyez la section "La philosophie Unix" sur cette page .


Pour souligner cette réponse, reportez-vous aux diapositives 4 à 9 de la présentation intitulée "Pourquoi Zsh est plus froid que votre shell".


Je suis conscient que la commande ci-dessus inclut un UUOC . Je le laisse tenir car c'est un espace réservé pour une commande arbitraire qui génère du texte.

Wildcard
la source
3
Petite note minuscule : sort -upeut faire le travail sort | uniqplus rapidement.
Iwillnotexist Idonotexist
cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100Vous en avez peut-être l'habitude, mais je n'appellerais pas ça du tout simple. Surtout la awkpartie.
Federico Poloni
Les pipes sont simples. J'ai effectivement dit: "... un pouvoir extraordinaire dans la combinaison d' outils simples (ou complexes) pour une tâche donnée".
Wildcard
5

J'ai donc essayé de faire quelques recherches à ce sujet en recherchant les manuels PDP-10 / TOPS-10 afin de connaître l'état de la technique avant la création de tuyaux. J'ai trouvé cela , mais TOPS-10 est remarquablement difficile à rechercher sur Google. Il existe quelques bonnes références sur l’invention du tuyau: une interview de McIlroy , sur l’histoire et l’impact d’UNIX .

Vous devez placer cela dans un contexte historique. Peu d'outils et de commodités modernes que nous prenons pour acquis existaient.

"Au début, Thompson ne programmait même pas sur le PDP, mais utilisait un ensemble de macros pour l'assembleur GEMAP sur une machine GE-635." (29) Une bande de papier a été générée sur le GE 635, puis testée sur PDP-7 jusqu’à ce que, selon Ritchie, "un noyau Unix primitif, un éditeur, un assembleur, un simple shell (interpréteur de commandes) et quelques utilitaires (comme les commandes Unix rm, cat, cp) soient terminés. En fait, le système d’exploitation était autonome, les programmes pouvaient être écrits et testés sans recourir à la bande de papier et le développement du PDP-7 se poursuivait. "

Un PDP-7 ressemble à ceci . Notez l'absence d'écran interactif ou de disque dur. Le "système de fichiers" serait stocké sur la bande magnétique. Il y avait jusqu'à 64 Ko de mémoire pour les programmes et les données.

Dans cet environnement, les programmeurs avaient tendance à s’adresser directement au matériel, par exemple en émettant des commandes permettant de faire tourner la bande et de traiter les caractères un par un, lus directement à partir de l’interface de la bande. UNIX a fourni des abstractions à ce sujet, de sorte que, plutôt que "lire à partir de téléscripteur" et "lire à partir d'une bande", elles soient combinées en une seule, avec l'ajout crucial de "lire à partir de la sortie d'un autre programme sans stocker de copie temporaire sur disque ou bande ".

Voici McIlroy sur l’invention de grep. Je pense que cela résume bien la quantité de travail requise dans l'environnement pré-UNIX.

"Grep a été inventé pour moi. Je concevais un programme pour lire le texte à voix haute à l'aide d'un synthétiseur vocal. En inventant des règles phonétiques, je vérifiais dans le dictionnaire Webster les mots sur lesquels ils pourraient échouer. Par exemple, comment gérez-vous le digramme?" ui ", qui se prononce de différentes manières:" fruit "," ruse "," coupable "," angoisse "," intuition "," béguine "? Je diviserais le dictionnaire en parties qui correspondaient au tampon et à l'utilisation limités d'ed une commande globale pour sélectionner une liste. Je réduirais cette liste par des balayages répétés avec ed pour voir comment chaque règle proposée fonctionnait. "

"Le processus était fastidieux et terriblement inutile, car le dictionnaire devait être divisé (on ne pouvait pas se permettre de laisser une copie divisée en ligne). Ensuite, copié chaque partie dans / tmp, scanné deux fois pour exécuter la commande g, et finalement jeté, ce qui prend du temps aussi. "

"Un après-midi, j’ai demandé à Ken Thompson s’il pouvait retirer le logiciel de reconnaissance des expressions régulières de l'éditeur et créer un programme en un seul passage. Il a dit oui. Le lendemain matin, j'ai trouvé dans mon courrier une note annonçant un programme nommé grep. Quand on lui a demandé ce que ce drôle de nom voulait dire, Ken a répondu que c’était évident. C’était la commande de l’éditeur qu’elle simulait, g / re / p (impression régulière globale). "

Comparez la première partie de celle-ci à l' cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100exemple. Si vous avez le choix entre "construire une ligne de commande" et "écrire un programme spécifiquement à cette fin, manuellement, en assembleur", il est intéressant de créer la ligne de commande. Même si cela prend quelques heures de lecture des manuels (papier) pour le faire. Vous pouvez ensuite l'écrire pour référence future.

pjc50
la source
1

Le génie de Pipes est de combiner trois idées importantes.

Premièrement, les pipes sont une implémentation pratique de «co-routines», un terme inventé par Conway en 1958, qui était prometteur mais qui n’avait guère d’utilisation pratique avant Pipes.

Deuxièmement, en mettant en œuvre des pipes dans le langage shell, Thompson et al. Ont inventé le premier véritable «langage de la colle».

Ces deux points permettent de développer efficacement des composants logiciels réutilisables dans un langage optimisé de bas niveau, puis de les coller pour former une fonctionnalité beaucoup plus grande et plus complexe. Ils ont appelé cela "Programmation dans le Grand".

Troisièmement, l'implémentation de canaux utilisant les mêmes appels système que ceux utilisés pour l'accès aux fichiers permettait aux programmes d'être écrits avec des interfaces universelles. Cela permettait de trouver des solutions véritablement universelles aux problèmes logiciels, pouvant être utilisées de manière interactive, en utilisant des données de fichiers et dans le cadre de systèmes logiciels plus vastes, le tout sans aucune modification des composants logiciels. Pas de compilation, pas de configuration, juste quelques commandes simples.

Si vous souhaitez suivre la courbe d'apprentissage, le logiciel UNIX est tout aussi utile aujourd'hui qu'il l'était il y a 40 ans. Nous réinventons constamment ce qu’ils savaient déjà et avons construit des solutions. Et la percée clé a été la simple pipe. La seule véritable innovation après cela a été la création d’Internet dans les années 80. De manière dramatique, UNIX a saboté son implémentation en créant une API séparée. Nous en subissons encore les conséquences ... Oh, oui, il y avait quelque chose avec les écrans vidéo et les souris qui est devenu populaire à la fin des années 80. Mais c'est pour les WIMP.

EvertW
la source