Qual è l'esatta ingegnosità del tubo Unix


52

Ho sentito la storia di come Douglas Mcllroy ha avuto l'idea e come Ken Thompson l'ha implementata in una notte.

Per quanto ho capito, pipe è una chiamata di sistema che condivide un pezzo di memoria tra due processi in cui un processo scrive e l'altro legge.

Come qualcuno che non ha familiarità con gli interni o i concetti del sistema operativo, mi chiedevo quale fosse esattamente il "genio" nella storia? È l'idea di due processi che condividono la memoria? O è l'implementazione? O entrambi?

PS: sono a conoscenza dell'utilità della pipe o di come usarla nella shell. La domanda riguarda il concetto e l'attuazione del|


4
Immagino che a quei tempi fosse abbastanza radicale spingere fortemente per implementare un meccanismo per comporre le applicazioni. Per fare ciò, dovresti avere una concezione ben definita di separazione dell'interfaccia dall'implementazione e realizzare l'utilità della composizione funzionale nella programmazione.
Chan-Ho Suh,

4
Non solo, già le applicazioni, mentre erano in esecuzione, avevano un handle di input standard e un handle di output standard, e le API del sistema operativo di tipo Unix avevano funzioni di lettura / scrittura da applicare a questi handle. L'uso intelligente di alcuni concetti ortogonali e di grande capacità (handle, output e input da essi) porta non solo alle pipe, ma anche a socket, interazioni personaggio-dispositivo e dozzine di altre cose. Quindi ora che abbiamo handle di file (per il tty che fornisce input da tastiera e output di testo) componiamo le applicazioni in modo che un'app diventi la tty dell'altra.
Warren P

6
@WarrenP realtà, Unix schiera standard input e standard di uscita a causa della la pipe()chiamata di sistema e |l'operatore shell (ref: McIlroy ). Oppure, come Voltaire avrebbe detto, " Se [stdio] non esistesse, sarebbe necessario inventarlo [:] " :-)
Ross Patterson,

Non esisteva un handle di file e un handle di entrata e di uscita fino a dopo i tubi?
Warren P

4
@WarrenP: Sembra che ciò che Patterson sta dicendo sia questo: prima c'erano gli handle di file. Quindi questi ragazzi hanno avuto l'idea che ogni programma era un handle di input e un handle di output per impostazione predefinita, che quindi consente ai programmi di concatenarsi banalmente. Questi sono diventati noti come input / output "standard".
Mooing Duck,

Risposte:


109

Per quanto ho capito, pipe è una chiamata di sistema che condivide un pezzo di memoria tra due processi in cui un processo scrive e l'altro legge.

In realtà, non esiste memoria condivisa. Il lettore e lo scrittore NON condividono alcuna parte del loro spazio di indirizzi e non utilizzano alcuna sincronizzazione esplicita.

I processi di lettura e scrittura stanno effettuando reade writele chiamate di sistema esattamente come farebbero se leggessero / scrivessero su un file. QUELLO è il genio ... l'innovazione: l'idea che la comunicazione (semplice) tra processi e l'I / O dei file possa essere gestita allo stesso modo ... dal punto di vista del programmatore dell'applicazione e dell'utente.

Una volta impostato il pipe, il sistema operativo (non il codice dell'applicazione o le librerie nello spazio utente) si occupa del buffering e del coordinamento. In modo trasparente.


Al contrario, prima dell'invenzione del concetto di pipe, se fosse necessario eseguire l'elaborazione "pipeline", in genere si otterrebbe un'applicazione per scrivere l'output in un file e, al termine, si eseguirà la seconda applicazione per leggere dal file.

In alternativa, se si desidera una vera pipeline, è possibile codificare entrambe le applicazioni per impostare un segmento di memoria condivisa (reale) e utilizzare semafori (o qualcosa) per coordinare la lettura / scrittura. Complicato ... e di conseguenza non spesso fatto.


34
"QUELLO è il genio ... l'innovazione: l'idea che la comunicazione tra processi e l'I / O dei file possano essere gestiti allo stesso modo" - esattamente questo. Ti permette di avere una comunicazione tra processi tra programmi che non sono mai stati progettati per averlo, e nemmeno (bisogno di) sapere cosa sta succedendo.
Guntram Blohm supporta Monica il

6
È anche utile notare che il motivo che utilizza l'I / O dei file per IPC è stato utile soprattutto perché Unix è stato progettato per l' elaborazione del testo : streaming di dati di testo da un programma all'altro, consentendo una composizione relativamente indolore, il che a sua volta ha permesso di costruire l'intero sistema da programmi relativamente semplici e di piccole dimensioni che trasmettevano dati l'uno dall'altro in (possibilmente) lunghe catene di operazioni semplici. Fondamentalmente, significava che hai un linguaggio relativamente flessibile per gestire l'elaborazione del testo.
Luaan,

1
E così "l'ingegnosità di Unix pipe" è "l'ingegnosità di Unix": tutti gli I / O (compresa la comunicazione tra processi, file standard e il resto degli oggetti del filesystem) sono gestiti come file.
Mark Hurd,

Un altro colpo di genio fu che UNIX sosteneva strutture di file leggibili dall'uomo in un momento in cui ogni byte contava ...
EvertW

14

Secondo me, il genio dell'idea di "tubi" è la semplicità d'uso.

Non è necessario effettuare chiamate di sistema, allocare memoria, nulla di complicato. Nella shell, è possibile utilizzare un singolo carattere: |. Ciò conferisce un potere straordinario nella combinazione di strumenti semplici (o complessi) per un determinato compito.

Prendi alcune attività quotidiane comuni come ordinare il testo in modo ordinato. Potresti avere un comando che elenca un sacco di nomi. (Per il mio esempio userò un file che contiene un sacco di nomi, per gentile concessione di listofrandomnames.com.) Usando le pipe puoi fare qualcosa del tipo:

$ 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

Questo è solo un esempio; ce ne sono migliaia. Per alcune altre attività specifiche che sono notevolmente semplificate dall'uso delle pipe, vedere la sezione "La filosofia Unix" in questa pagina .


Per sottolineare questa risposta, vedere le diapositive da 4 a 9 della presentazione, "Perché Zsh è più interessante di Shell."


Sono consapevole che il comando sopra include un UUOC . L'ho lasciato stare perché è un segnaposto per un comando arbitrario che genera testo.


3
Piccola piccola nota : sort -upuò fare il lavoro sort | uniqpiù velocemente.
Iwillnotexist Idonotexist,

cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100Potresti esserci abituato, ma non lo definirei affatto semplice. Soprattutto la awkparte.
Federico Poloni,

I tubi sono semplici. Ho detto, "... straordinario potere nella combinazione di strumenti semplici (o complessi) per un determinato compito."
Wildcard il

5

Quindi ho cercato di fare un po 'di ricerca su questo, cercando i manuali PDP-10 / TOPS-10 al fine di scoprire quale fosse lo stato dell'arte prima delle pipe. Ho trovato questo , ma TOPS-10 è straordinariamente difficile da google. Ci sono alcuni buoni riferimenti sull'invenzione della pipa: un'intervista a McIlroy , sulla storia e l'impatto di UNIX .

Devi metterlo nel contesto storico. Pochi degli strumenti e delle comodità moderni che diamo per scontati esistevano.

"All'inizio Thompson non programmava nemmeno sul PDP stesso, ma utilizzava una serie di macro per l'assemblatore GEMAP su una macchina GE-635." (29) Un nastro di carta è stato generato su GE 635 e poi testato su il PDP-7 fino a quando, secondo Ritchie, "furono completati un kernel Unix primitivo, un editor, un assemblatore, una semplice shell (interprete di comandi) e alcune utility (come i comandi Unix rm, cat, cp). punto, il sistema operativo era autoportante, i programmi potevano essere scritti e testati senza ricorrere al nastro di carta e lo sviluppo continuava sul PDP-7 stesso. "

Un PDP-7 è simile a questo . Si noti la mancanza di un display interattivo o di un disco rigido. Il "filesystem" verrebbe memorizzato sul nastro magnetico. Fino a 64 KB di memoria erano disponibili per programmi e dati.

In quell'ambiente, i programmatori tendevano a rivolgersi direttamente all'hardware, ad esempio inviando comandi per far girare il nastro ed elaborare i caratteri uno alla volta, letti direttamente dall'interfaccia del nastro. UNIX ha fornito astrazioni su questo, così che piuttosto che "leggere dal teletipo" e "leggere dal nastro" essendo interfacce separate sono state combinate in una, con l'aggiunta fondamentale di "leggere dall'output di un altro programma senza archiviare una copia temporanea sul disco o nastro ".

Ecco McIlroy sull'invenzione di grep. Penso che questo faccia un buon lavoro nel riassumere la quantità di lavoro richiesta nell'ambiente pre-UNIX.

"Grep è stato inventato per me. Stavo realizzando un programma per leggere il testo ad alta voce attraverso un sintetizzatore vocale. Mentre inventavo le regole fonetiche, avrei controllato il dizionario Webster per le parole su cui avrebbero potuto fallire. Ad esempio, come affrontare il digraph ' ui ', che è pronunciato in molti modi diversi:' frutto ',' astuzia ',' colpevole ',' angoscia ',' intuitivo ',' beghina '? Vorrei spezzare il dizionario in pezzi che si adattano al buffer limitato di ed e uso un comando globale per selezionare un elenco. Vorrei sminuire l'elenco con ripetute scansioni con ed per vedere come funzionava ciascuna regola proposta. "

"Il processo è stato noioso e terribilmente dispendioso, dal momento che il dizionario doveva essere diviso (uno non poteva permettersi di lasciare una copia divisa in linea). Quindi ha copiato ogni parte in / tmp, scansionandola due volte per eseguire il comando g, e alla fine l'ha buttato via, il che richiede tempo. "

"Un pomeriggio ho chiesto a Ken Thompson se fosse in grado di estrarre il riconoscitore di espressioni regolari dall'editor e creare un programma one-pass per farlo. Ha detto di sì. La mattina dopo ho trovato un messaggio nella mia mail che annunciava un programma chiamato grep. Ha funzionato come un incantesimo. Alla domanda su cosa significasse quel nome divertente, Ken ha detto che era ovvio. Stava per il comando dell'editor che simulava, g / re / p (stampa di espressioni regolari globali). "

Confronta la prima parte di questo con l' cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100esempio. Se le tue opzioni sono "costruisci una riga di comando" anziché "scrivi un programma appositamente per lo scopo, manualmente, in assemblatore", allora vale la pena costruire la riga di comando. Anche se ci vogliono alcune ore per leggere i manuali (cartacei) per farlo. È quindi possibile scriverlo per riferimento futuro.


1

Il genio di Pipes è che unisce tre idee importanti.

In primo luogo, i tubi sono un'implementazione pratica di "co-routine", un termine coniato da Conway nel 1958 che era promettente ma vide poco uso pratico prima di Pipes.

In secondo luogo, implementando le pipe nel linguaggio shell, Thompson et al hanno inventato il primo vero "linguaggio colla".

Questi due punti consentono di sviluppare in modo efficiente componenti software riutilizzabili in un linguaggio ottimizzato di basso livello e di incollarli per formare funzionalità molto più grandi e complesse. Hanno chiamato questa "programmazione in grande".

In terzo luogo, l'implementazione di pipe utilizzando le stesse chiamate di sistema utilizzate per l'accesso ai file ha permesso di scrivere programmi con interfacce universali. Ciò ha consentito soluzioni veramente universali ai problemi del software, che possono essere utilizzate in modo interattivo, utilizzando i dati dei file e come parte di sistemi software più grandi, il tutto senza una singola modifica ai componenti del software. Nessuna compilazione, nessuna configurazione, solo alcuni semplici comandi della shell.

Se ti interessa attraversare la curva di apprendimento, il software UNIX è utile oggi come lo era 40 anni fa. Reinventiamo costantemente cose che già conoscevano e costruivano soluzioni. E la svolta chiave è stata la semplice Pipe. L'unica vera innovazione è stata la creazione di Internet negli anni '80. Drammaticamente, UNIX ha fallito la sua implementazione creando un'API separata. Subiamo ancora le conseguenze ... Oh, sì, c'era qualcosa con display video e topi che è diventato popolare alla fine degli anni '80. Ma questo è per i WIMP.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.