Pipes e filtros

Origem: Wikipédia, a enciclopédia livre.
Ir para: navegação, pesquisa

Capturar.PNG Pipes e Filtros é um estilo arquitetural (Engenharia de Software) composto por uma cadeia de elementos de processamento, dispostos de forma tal que a saída de cada elemento é a entrada do próximo. É considerado como uma rede pela qual os dados fluem de uma extremidade (origem) à outra (destino). O fluxo de dados se dá através de pipes (canos) e os dados sofrem transformações quando processados nos filtros.

Em outras palavras, os pipes é que possibilitam o fluxo dos dados, e os filtros fazem o processamento dos mesmos, colocando-os nos pipes antes que todos os dados de entrada sejam consumidos. Percebemos aí que os filtros e pipes funcionam de forma interativa, ressaltando que um pipe pode ser conectado a um filtro, mas pipes não podem ser conectados a pipes e tampouco filtros podem ser conectados a filtros. Portanto, a nível de arquitetura, o processamento é mapeado em filtros e os pipes agem como condutores de dados. Recombinando-se filtros, é possível construir famílias de sistemas relacionados.

Indicações[editar | editar código-fonte]

O uso de Pipes e Filtros é indicado para dividir uma tarefa de processamento maior em uma sequência de pequenas dimensões, ou seja, esse processamento será dividido em filtros e ocorrerá em etapas independentes, conectadas pelos pipes.

Vantagens[editar | editar código-fonte]

As vantagens de utilizar o modelo arquitetural de Pipes e Filtros é que estes podem ser vistos como caixas pretas, onde há encapsulamento, alta coesão, recombinação e reuso dos dados. Isso implica afirmar que esse estilo tem suporte à reutilização. Além disso, os filtros interagem com os outros componentes de forma limitada - o que leva a um baixo acoplamento. O mais relevante é que o sistema pode ser facilmente estendido e modificado, facilitando a implementação em processadores paralelos ou em múltiplas threads em processadores simples.

Desvantagens[editar | editar código-fonte]

As desvantagens de utilizar esse estilo arquitetural é que, devido o processamento ocorrer em lotes, é dificil criar aplicações interativas. Geralmente filtros exigem que os dados sejam representados no denominador comum mais baixo, tipicamente fluxos de bytes ou caracteres. Esse estilo arquitetural também pode introduzir sobrecarga para analisar o fluxo de dados, podendo haver a exigência de um buffer de tamanho limitado, que devido à essa limitação, pode causar um deadlock. Todas essas desvantagens geram uma baixa performance.

Implementação de pipes e filtros[editar | editar código-fonte]

Para a implementação de pipes e filtros, devem-se seguir os seguintes passos:

1. Dividir a tarefa do sistema em uma sequência de estágios de processamento:

  • Cada estágio deve depender somente da saída de seu predecessor

2. Definir o formato dos dados a serem passados ao longo de cada pipe

  • Formato padrão → flexibilidade

3. Decidir como implementar cada conexão pipe

  • Implica definir se os filtros adjacentes são ativos ou passivos

4. Projetar e implementar os filtros

  • Além dos pipes, baseia-se também na tarefa que eles devem realizar
  • Passivos: funções (PULL) ou procedimentos (PUSH)
  • Ativos: processos ou threads

5. Projetar o tratamento de erro

  • Difícil devido a não existência de estado global
  • No mínimo, deve haver detecção de erro
  • Se um filtro “capota” → Resincronização

6. Ajustar o pipeline de processamento

Pipes e Filtros Multiprocessados[editar | editar código-fonte]

Oleodutos são freqüentemente implementados em um Sistema Operacional multitarefa através do lançamento de todos os elementos ao mesmo tempo como processos distintos, e automaticamente fazendo a manutenção dos dados lidos de cada processo com os dados escritos pelos processo anteriores.

Desta forma, a CPU será naturalmente ligada entre os processos pelo agendador de tarefas de modo a minimizar o tempo ocioso. Em outros modelos comuns, os elementos são implementadas como threads leves ou como co-rotinas para reduzir a sobrecarga do Sistema Operacional. Dependendo do Sistema Operacional, os segmentos podem ser agendadas diretamente pelo sistema ou por um gerenciador de threads.

Normalmente, ler e escrever reque um pedido de interrupção, o que significa que a execução do processo de origem, sobre a escrita, seja suspensa até que todos os dados possam ser gravados no processo de destino, e, igualmente, a execução do processo de destino, após a leitura, será suspensa até que pelo menos alguns dos dados solicitados possam ser obtidos a partir do processo de origem. Obviamente, isso não pode causar um deadlock, onde dois processos esperam indefinidamente pela resposta do outro, uma vez que pelo menos um dos dois processos será atendido logo em seguida pelo sistema operacional, e continua a executar normalmete.

Para melhorar o desempenho, a maioria dos sistemas operacionais que implementa pipe ,usa buffer de pipes, que permitem que o processo de origem forneça mais dados do que o processo de destino é capaz de receber. Na maioria dos Unix e sistemas operacionais baseados no Unix, está disponível um comando especial que implementa um buffer de pipe com dimensões muito maiores e configurável. Este comando pode ser útil se o processo de destino é significativamente mais lento do que o processo de origem, mas mesmo assim é desejável que o processo de origem possa completar sua tarefa o mais rapidamente possível. Por exemplo, se o processo de origem consiste em ler uma faixa de áudio de um CD e o processo de destino comprime os dados Wave para o formato MP3. Neste caso, toda a faixa estaria armazenada em um buffer de piper, o que faria a unidade de CD parar de girar mais rapidamente, e permitir que o usuário remova o CD da unidade antes que o processo de codificação seja concluído.

Tais buffer's de comando podem ser implementados usando primitivas de leitura e escrita disponíveis no sistema operacional. A ociosidade pode ser evitado pelo uso de votação, seleção ou multithreading.

VM / CMS e MVS

[Editando...]

Pipes e Filtros de Objetos[editar | editar código-fonte]

Paralelo ao modelo Pipe e Filtro baseado em fluxo de dados, há também o Pipe e Filtro de Objetos. Em um pipe e filtro de objetos, os Filtros processam objetos em sua saída ao invés de textos, eliminando assim a necessidade de analisar a cadeia de caracteres, tarefa comum em scripts do shell do UNIX. Windows PowerShell usa esse esquema e transfere objetos .NET. Canais de comunicação, encontrado na linguagem de programação Limbo e em IPython com a extensão ipipe são outros exemplos desta metáfora.

Pipe e Filtros em GUI's[editar | editar código-fonte]

Ambientes gráficos como o Sistema Operacional RISC e ROX Desktop também fazem uso Pipes e Filtros. Ao invés de fornecer uma caixa de diálogo contendo um gerrenciador de arquivos que permite ao usuário especificar onde um programa deve guardar os dados, RISC OS e ROX fornecem uma caixa de diálogo com um ícone (e um campo para especificar o nome). O destino é especificado por arrastando e soltando o ícone. O usuário pode soltar o ícone em qualquer lugar, inclusive sobre os ícones de outros programas, e um arquivo já salvo poderia ser descartado.

Por exemplo, um usuário navegando na internet poderá ver uma imagem que deseja editar e upar través de um arquivo comprimido .gz.

Usando pipes e filtros em GUI's, ele poderia arrastar o link para o programa que salva arquivos, arrastar o ícone que representa o conteúdo extraído para seu editor de imagens, editá-lo, abrir o diálogo Salvar Como e arrastar o ícone para seu programa de upload.

Conceitualmente, este método poderia ser usado com uma caixa de diálogo 'salvar' convencional, mas isso exigiria que os programas do usuário para ter uma posição óbvia e acessível no sistema de arquivos para poder navegar. Na prática, isto é pouco implementado, pipe e filtros em GUI são raros.

História[editar | editar código-fonte]

O processo em pipe e filtros foi inventado por Douglas McIlroy, um dos criadores dos primeiros shells Unix, e muito contribuiu para a popularidade desse sistema operacional. Pode ser considerada a primeira instância de componente de software não trivial.

A idéia acabou sendo importada para outros sistemas operacionais, como DOS, OS/2, Windows NT, BeOS, AmigaOS, MorphOS e Mac OS X.