Qual é a ingenuidade exata do pipe Unix

52

Eu ouvi a história de como Douglas Mcllroy surgiu com o conceito e como Ken Thompson o implementou em uma noite.

Até onde eu entendi, pipe é uma chamada de sistema que compartilha um pedaço de memória entre dois processos em que um processo grava e outro lê.

Como alguém que não está familiarizado com conceitos ou componentes internos do sistema operacional, eu queria saber qual é exatamente o "gênio" da história? É a idéia de dois processos que compartilham memória? Ou é a implementação? Ou ambos?

PS: Estou ciente da utilidade do tubo ou de como usá-lo com casca. A questão é sobre o conceito e a implementação do|

aoak
fonte
4
Eu acho que naqueles dias, era bastante radical insistir fortemente na implementação de um mecanismo para compor aplicativos. Para fazer isso, você precisa ter uma concepção bem formada de separação da interface da implementação e perceber a utilidade da composição funcional na programação.
Chan-Ho Suh
4
Além disso, os aplicativos em execução já tinham um identificador de entrada padrão e um identificador de saída padrão, e as APIs do sistema operacional do tipo Unix tinham funções de leitura / gravação para aplicar a esses identificadores. O uso inteligente de alguns conceitos ortogonais e altamente capazes (identificadores, saída e entrada deles) leva não apenas a tubos, mas também a soquetes, interações entre caracteres e dispositivos e dezenas de outras coisas. Portanto, agora que temos identificadores de arquivo (para o tty que fornece entrada de teclado e saída de texto) vamos compor aplicativos para que um aplicativo se torne o tty do outro.
Warren P
6
@WarrenP Na verdade, Unix obteve-padrão de entrada e de saída de padrão por causa do pipe()syscall e o |operador de concha (ref: Mcllroy ). Ou, como Voltaire poderia ter dito: " Se [stdio] não existisse, seria preciso inventá [ele]. " :-)
Ross Patterson
Não havia um identificador de arquivo e um identificador de entrada e saída até DEPOIS dos tubos?
Warren P
4
@ WarrenP: Parece que o que Patterson está dizendo é o seguinte: primeiro, houve identificadores de arquivo. Então, esses caras tiveram a ideia de que cada programa é um identificador de entrada e identificador de saída por padrão, o que permite que os programas sejam encadeados trivialmente. Estes tornaram-se conhecidos como entrada / saída "padrão".
Mooing Duck

Respostas:

109

Até onde eu entendi, pipe é uma chamada de sistema que compartilha um pedaço de memória entre dois processos em que um processo grava e outro lê.

Na verdade, não há memória compartilhada envolvida. O leitor e o gravador NÃO estão compartilhando nenhuma parte do espaço de endereço e não estão usando nenhuma sincronização explícita.

Os processos de leitura e gravação estão fazendo reade as writechamadas do sistema exatamente como fariam se estivessem lendo / gravando em um arquivo. Esse é o gênio ... a inovação: a noção de que a comunicação (simples) entre processos e a E / S de arquivo podem ser tratadas da mesma maneira ... da perspectiva do programador de aplicação e do usuário.

Após a instalação do canal, o sistema operacional (não o código do aplicativo ou as bibliotecas no espaço do usuário) cuida do buffer e da coordenação. Transparentemente.


Por outro lado, antes da invenção do conceito de canal, se você precisasse processar o "pipeline", normalmente você teria uma saída de gravação de um aplicativo em um arquivo e, quando terminar, executaria o segundo aplicativo para ler a partir do Arquivo.

Como alternativa, se você quisesse um pipeline verdadeiro, poderia codificar os dois aplicativos para configurar um segmento de memória compartilhada (real) e usar semáforos (ou algo assim) para coordenar a leitura / gravação. Complicado ... e, como consequência, nem sempre é feito.

Stephen C
fonte
34
"Esse é o gênio ... a inovação: a noção de que o processo de comunicação e E / S de arquivo pode ser tratado da mesma maneira" - exatamente isso. Ele permite que você tenha comunicação entre processos entre os programas que nunca foram projetados para tê-la, e nem precisa (saber) o que está acontecendo.
Guntram Blohm apoia Monica
6
Também é útil observar que o motivo do uso de E / S de arquivo para IPC foi útil principalmente porque o Unix foi projetado para processamento de texto - transmitindo dados de texto de programa para programa, permitindo uma composição relativamente indolor, o que, por sua vez, significava que todo o sistema poderia ser construído a partir de programas relativamente simples e pequenos que transmitiam dados de um para outro em (possivelmente) longas cadeias de operações simples. Basicamente, significava que você tinha uma linguagem relativamente flexível para lidar com o processamento de texto.
Luaan
11
E assim a "engenhosidade do Unix pipe" é a "engenhosidade do Unix": todas as E / S (incluindo comunicação entre processos, arquivos padrão e o restante dos objetos do sistema de arquivos) são tratadas como arquivos.
Mark Hurd
Outro golpe de génio foi que UNIX defendido estruturas de arquivos legíveis em uma época em que cada byte contado ...
EvertW
14

Na minha opinião, o gênio da idéia de "tubos" é a simplicidade de uso.

Você não precisa fazer chamadas do sistema, alocar memória, nada complicado. No shell, você pode usar um único caractere: |. Isso fornece um poder extraordinário na combinação de ferramentas simples (ou complexas) para uma determinada tarefa.

Execute algumas tarefas diárias comuns, como classificar o texto ordenadamente. Você pode ter um comando que lista um monte de nomes. (No meu exemplo, usarei um arquivo que contém vários nomes, cortesia de listofrandomnames.com.) Usando pipes, você pode fazer algo como o seguinte:

$ 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

Isso é apenas um exemplo; existem milhares. Para algumas outras tarefas específicas que são notavelmente mais fáceis com o uso de pipes, consulte a seção "A filosofia do Unix" nesta página .


Para destacar essa resposta, consulte os slides 4 a 9 da apresentação "Por que o Zsh é mais legal que o seu shell"?


Estou ciente de que o comando acima inclui um UUOC . Eu deixei de lado, porque é um espaço reservado para um comando arbitrário que gera texto.

Curinga
fonte
3
Pequena nota minúscula : sort -upode fazer o trabalho de maneira sort | uniqmais rápida.
Iwillnotexist Idonotexist
cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100Você pode estar acostumado, mas eu não chamaria isso de simples. Especialmente a awkparte.
Federico Poloni
Os tubos são simples. Eu disse: "... poder extraordinário na combinação de ferramentas simples (ou complexas) para uma determinada tarefa".
Wildcard
5

Então, tentei fazer um pouco de pesquisa sobre isso, procurando os manuais PDP-10 / TOPS-10 para descobrir qual era o estado da arte antes dos tubos. Achei isso , mas o TOPS-10 é notavelmente difícil de pesquisar no Google. Existem algumas boas referências sobre a invenção do pipe: uma entrevista com McIlroy , sobre a história e o impacto do UNIX .

Você tem que colocar isso no contexto histórico. Poucas das ferramentas e conveniências modernas que tomamos como garantidas existiam.

"No início, Thompson nem programava no próprio PDP, mas usava um conjunto de macros para o montador GEMAP em uma máquina GE-635". (29) Uma fita de papel foi gerada no GE 635 e depois testada em o PDP-7 até que, de acordo com Ritchie, "um kernel Unix primitivo, um editor, um assembler, um shell simples (interpretador de comandos) e alguns utilitários (como os comandos rm, cat, cp do Unix) foram concluídos. Nesse ponto, o sistema operacional era autossuficiente, os programas podiam ser escritos e testados sem recorrer à fita de papel e o desenvolvimento continuou no próprio PDP-7 ".

Um PDP-7 se parece com isso . Observe a falta de uma tela interativa ou disco rígido. O "sistema de arquivos" seria armazenado na fita magnética. Havia até 64kB de memória para programas e dados.

Nesse ambiente, os programadores tendiam a endereçar o hardware diretamente, como emitindo comandos para girar a fita e processar os caracteres, um de cada vez, lidos diretamente na interface da fita. O UNIX forneceu abstrações sobre isso, de modo que, em vez de "ler do teletipo" e "ler da fita" serem interfaces separadas, elas foram combinadas em uma, com a adição de canal crucial de "leitura da saída de outro programa sem armazenar uma cópia temporária no disco" ou fita ".

Aqui está McIlroy sobre a invenção de grep. Eu acho que isso faz um bom trabalho de resumir a quantidade de trabalho necessária no ambiente pré-UNIX.

"O Grep foi inventado para mim. Eu estava criando um programa para ler texto em voz alta por meio de um sintetizador de voz. Como eu inventei as regras fonéticas, verificaria o dicionário de Webster em busca de palavras que possam falhar. Por exemplo, como você lida com o dígrafo ' ui ', que é pronunciado de várias maneiras diferentes:' fruit ',' guile ',' culpado ',' angústia ',' intuit ',' beguine '? Eu dividiria o dicionário em pedaços que se encaixam no buffer limitado do ed um comando global para selecionar uma lista. Eu desagregaria essa lista repetindo varreduras com ed para ver como cada regra proposta funcionava. "

"O processo foi tedioso e terrivelmente inútil, já que o dicionário teve que ser dividido (não era possível deixar uma cópia dividida on-line). Em seguida, ed copiou cada parte para / tmp, digitalizou-a duas vezes para realizar o comando g, e finalmente jogou fora, o que também leva tempo ".

"Uma tarde, perguntei a Ken Thompson se ele poderia retirar o reconhecedor de expressões regulares do editor e criar um programa de uma passagem para fazê-lo. Ele disse que sim. Na manhã seguinte, encontrei uma nota no meu correio anunciando um programa chamado grep. Funcionou como um encanto. Quando perguntado sobre o que esse nome engraçado significava, Ken disse que era óbvio. Representava o comando do editor que simulava g / re / p (expressão regular global impressa) ".

Compare a primeira parte disso com o cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100exemplo. Se suas opções são "construir uma linha de comando" versus "escrever um programa especificamente para esse fim, manualmente, em assembler", vale a pena construir a linha de comando. Mesmo que demore algumas horas lendo os manuais (em papel) para fazê-lo. Você pode anotá-lo para referência futura.

pjc50
fonte
1

O gênio do Pipes é que ele combina três idéias importantes.

Primeiro, os pipes são uma implementação prática de 'co-rotinas', um termo cunhado por Conway em 1958, que foi promissor, mas teve pouco uso prático antes de Pipes.

Em segundo lugar, implementando pipes na linguagem shell, Thompson et al. Inventaram a primeira 'linguagem de cola' real.

Esses dois pontos permitem que componentes de software reutilizáveis ​​sejam desenvolvidos eficientemente em uma linguagem otimizada de baixo nível e colados juntos para formar uma funcionalidade muito maior e mais complexa. Eles chamavam isso de 'Programação em grandes'.

Em terceiro lugar, a implementação de pipes usando as mesmas chamadas de sistema usadas para acesso a arquivos permitiu que programas fossem gravados com interfaces universais. Isso permitiu soluções verdadeiramente universais para problemas de software, que podem ser usadas interativamente, usando dados de arquivos e como parte de sistemas de software maiores, tudo sem uma única alteração nos componentes de software. Sem compilação, sem configuração, apenas alguns comandos simples do shell.

Se você deseja seguir a curva de aprendizado, o software UNIX é tão útil hoje quanto era há 40 anos. Estamos constantemente reinventando coisas para as quais eles já sabiam e construíram soluções. E a principal inovação foi o simples Pipe. A única inovação real depois disso foi a criação da internet nos anos 80. Dramaticamente, o UNIX estragou sua implementação criando uma API separada. Ainda sofremos as consequências ... Ah, sim, houve algo com monitores de vídeo e ratos que se tornou popular no final dos anos 80. Mas isso é para WIMPs.

EvertW
fonte