web-dev-qa-db-fra.com

Quelle est l'ingéniosité exacte du tuyau Unix

J'ai entendu l'histoire de la façon dont Douglas Mcllroy a conçu le concept et comment Ken Thompson l'a mis en œuvre en une nuit.

Pour autant que je sache, pipe est un appel système qui partage un morceau de mémoire entre deux processus où un processus écrit et l'autre lit.

En tant que personne qui n'est pas familière avec les concepts internes ou les systèmes d'exploitation, je me demandais quel est 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 connais l'utilité de la pipe ou comment l'utiliser dans Shell. La question porte sur le concept et la mise en œuvre du |

53
aoak

Pour autant que je sache, pipe est un appel système qui partage un morceau de mémoire entre deux processus où un processus écrit et l'autre lit.

En fait, aucune mémoire partagée n'est 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 des appels système read et writeexactement comme ils le feraient s'ils lisaient de/écrit dans un fichier. C'EST le génie ... l'innovation: l'idée que la communication (simple) interprocessus et les E/S de fichiers peuvent être traitées de la même manière ... du point de vue du programmeur d'application et de l'utilisateur.

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


En revanche, avant l'invention du concept de tuyau, si vous aviez besoin de faire un traitement "pipeline", vous auriez généralement une sortie d'écriture d'application dans un fichier, puis lorsqu'elle serait terminée, vous exécuteriez la deuxième application pour lire à partir du fichier.

Alternativement, si vous vouliez un vrai pipeline, vous pouvez coder les deux applications pour configurer un segment de mémoire partagée (réel) et utiliser des sémaphores (ou quelque chose) pour coordonner la lecture/écriture. Compliqué ... et par conséquent pas souvent fait.

109
Stephen C

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

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

Effectuez des tâches quotidiennes courantes, comme trier le texte avec soin Vous pouvez avoir une commande qui répertorie tout un tas de noms. (Pour mon exemple, je vais utiliser un fichier qui contient un tas de noms, gracieuseté de listofrandomnames.com.) En utilisant des tuyaux, vous pouvez faire quelque chose comme ceci:

$ 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

Ce 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 tuyaux, voir la section "La philosophie Unix" sur cette page .


Pour souligner cette réponse, voir les diapositives 4 à 9 de la présentation, "Pourquoi Zsh est plus cool que votre shell."


Je suis conscient que la commande ci-dessus inclut un UUOC . Je le laisse reposer car il s'agit d'un espace réservé pour une commande arbitraire qui génère du texte.

14
Wildcard

J'ai donc essayé de faire un peu de recherche à ce sujet en recherchant des manuels PDP-10/TOPS-10 afin de découvrir l'état de l'art avant les tuyaux. J'ai trouvé ceci , mais TOPS-10 est remarquablement difficile à google. Il y a quelques bonnes références sur l'invention de la pipe: ne interview avec McIlroy , sur l'histoire et l'impact d'UNIX .

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

"Au début, Thompson n'a même pas programmé sur le PDP lui-même, mais a plutôt utilisé 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 le 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. point, le système d'exploitation était autosuffisant, les programmes pouvaient être écrits et testés sans recourir à la bande papier, et le développement s'est poursuivi sur le PDP-7 lui-même. "

n PDP-7 ressemble à ceci . Notez l'absence d'affichage 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 à adresser le matériel directement, par exemple en émettant des commandes pour faire tourner la bande et traiter les caractères lus un à la fois directement à partir de l'interface de la bande. UNIX a fourni des abstractions à ce sujet, de sorte que plutôt que "lire à partir du téléscripteur" et "lire à partir de la bande" soient des interfaces distinctes, elles ont été combinées en une seule, avec l'ajout crucial de tuyaux "lu à partir de la sortie d'un autre programme sans stocker une copie temporaire sur le 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 faisais un programme pour lire du texte à haute voix à travers un synthétiseur vocal. Comme j'ai inventé des règles phonétiques, je vérifierais le dictionnaire de Webster pour les mots sur lesquels ils pourraient échouer. Par exemple, comment faites-vous face au digraphe" ui ', qui se prononce de différentes manières:' fruit ',' guile ',' coupable ',' angoisse ',' intuit ',' beguine '? Je décomposerais le dictionnaire en morceaux qui correspondent au tampon limité et à l'utilisation d'ed une commande globale pour sélectionner une liste. Je réduirais cette liste par des analyses répétées 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 fractionnée en ligne). Ensuite, ed a copié chaque partie dans/tmp, l'a scannée deux fois pour exécuter la commande g, et finalement jeté, ce qui prend aussi du temps. "

"Un après-midi, j'ai demandé à Ken Thompson s'il pouvait retirer le module de reconnaissance des expressions régulières de l'éditeur et créer un programme en une passe pour le faire. Il a dit oui. Le lendemain matin, j'ai trouvé une note dans mon courrier annonçant un programme nommé grep. Cela a fonctionné comme un charme. Lorsqu'on lui a demandé ce que ce nom drôle signifiait, Ken a dit que c'était évident. Il représentait la commande de l'éditeur qu'il simulait, g/re/p (impression d'expression régulière globale). "

Comparez la première partie de cela au cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100 exemple. Si vos options sont "construire une ligne de commande" contre "écrire un programme spécifiquement pour le but, à la main, dans l'assembleur", alors cela vaut la peine de construire 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.

5
pjc50

Le génie de Pipes est qu'il combine trois idées importantes.

Premièrement, les tuyaux sont une mise en œuvre pratique des "co-routines", un terme inventé par Conway en 1958 qui était prometteur mais qui a vu peu d'utilisation pratique avant les tuyaux.

Deuxièmement, en mettant en œuvre des tuyaux dans le langage Shell, Thompson et al ont inventé le premier véritable "langage de la colle".

Ces deux points permettent aux composants logiciels réutilisables d'être développés efficacement dans un langage optimisé de bas niveau, puis collés ensemble pour former des fonctionnalités beaucoup plus grandes et plus complexes. Ils ont appelé cela "Programmation à grande échelle".

Troisièmement, l'implémentation de canaux utilisant les mêmes appels système que ceux utilisés pour l'accès aux fichiers a permis d'écrire des programmes avec des interfaces universelles. Cela a permis des solutions vraiment universelles aux problèmes logiciels, qui peuvent être utilisées de manière interactive, en utilisant des données provenant de fichiers, et dans le cadre de systèmes logiciels plus grands, le tout sans une seule modification des composants logiciels. Pas de compilation, pas de configuration, juste quelques commandes Shell simples.

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

1
EvertW