Entendendo Pipe e FIFO (parte 1)

Pipes e FIFOs são muito utilizados no mundo Linux como um método de IPC (inter process communication), ou comunicação entre processos. Muitas das vezes nem percebemos que estamos usando-os pela sua facilidade. Normalmente usamos pipes no shell, como no comando abaixo:

ls | wc -l

Neste comando, o shell executa o comando ls, pegando todo o conteúdo de saída e o direciona para a entrada do processo wc, que é criado logo em seguida, tudo de um jeito simples de escrever.

Pipes na verdade agem como “canos” que conectam processos unidirecionalmente. Ou seja, todo o pipe tem um lado que escreve dados e outro que lê estes dados. Vejamos o código abaixo onde mostramos onde dois processos leem e escrevem no pipe recém-criado:

É um código um pouco extenso de começo, mas após a explicação ele se torna de fácil leitura. Aqui podemos verificar que a chamada de sistema pipe é executada, recebendo como parâmetro um array de inteiros de duas posições. Se a chamada for executada com sucesso, o array de inteiros terá dois files descriptors para o pipe. A posição zero do array contém o fd de leitura do pipe, e a posição um contém o fd de escrita.

Podemos verificar que após a chamada pipe ser executada, um fork é feito. O fork nada mais é que a criação de um novo processo, onde este novo processo começa a executar do ponto em que foi executado o fork. O retorno da chamada fork é utilizado para identificar qual processo é o pai e qual é o filho. Desta forma um switch-case é utilizado para separar os trechos de código que devem ser executados pelo processo pai e processo filho. Neste momento não é possível saber qual dos dois processos irá executar primeiro, pois os dois são concorrentes perante a CPU.

Explicado o fork, podemos nos atrelar ao real funcionamento do exemplo, onde o processo pai irá escrever uma mensagem no pipe, e esta mensagem deve ser lida pelo processo filho. Após o fork, o processo pai fecha o file descriptor de leitura, e o processo filho fecha o file descriptor de escrita, uma vez que o processo pai somente irá escrever no pipe e o processo filho irá fazer a leitura. Neste ponto, o processo filho executa a chamada read que lê dados do file descriptor de leitura do pipe, e então o processo filho fica esperando por dados a serem lidos. Ao mesmo tempo, o processo pai escreve uma mensagem utilizando o file descriptor de escrita utilizando a chamada de sistema write.

Toda esta informação junta pode dar uma certa confusão no inicial. Para fins de simplificar o exemplo, abaixo consta como compilar e executar o programa, e a saída do mesmo.

Para compilar, invocamos o GCC:
gcc pipe.c -Wall -o pipe

Execuntado e mostrando a saída do exemplo:
[email protected]: [pipe_fifo] # ./pipe
Parent wrote the message!
Child readed: Hello from parent! Have a long life!

Você pode alterar o código e verificar a saída do mesmo para um melhor entendimento do que realmente acontece.

Alguns pontos interessantes sobre o uso de pipes:

  • Se mais de um processo ou thread está escrevendo no pipe ao mesmo tempo, o kernel assegura que as escritas serão atômicas, ou seja, não haverá interrupções de escritas, desde que o número de bytes escritos seja menor ou igual PIPE_BUF. Esta definição está dentro do arquivo /usr/include/linux/limits.h e no meu sistema ele tem o valor de 4096.
  • A capacidade de um pipe de reter informação é limitada. Desde a versão 2.6.11 do Linux o limite de dados que um pipe pode armazenar é 65536 bytes. Mas, uma vez que uma aplicação for bem desenhada e que o lado de leitura do pipe consiga ler assim que o dado está disponível, não haverá problemas com esta limitação.
  • Pipes podem somente ser usados por processos afiliados, ou seja, processos pai com processos filhos, netos e etc. Existe um tipo de pipe que pode ser usado por processos diferentes. Este se chama FIFO e será abordado nas próximas postagens.

Espero que tenham gostado desta primeira parte do artigo. A segunda parte terá informações que explicam como o bash consegue conectar a saída de um processo com a entrada de um novo processo. Não se esqueçam de nos seguir nas redes sociais para ler as postagens assim que estas são publicadas. Até mais!

  • Xinuo

    Pipes NÃO são como canos que unem os processos unidirecionalmente, como vc afirmou. Pense assim: num cano, algo que passa nele, também pode voltar. Se pensar em cachimbo da paz, pense no índio que lhe dá o cachimbo para dar uma tragada, vc passa ele de volta e depois da tragada dele, ele passa de volta para vc, e assim vai.

    Então eu digo: “pipes” são como chamadas telefônicas, que abrem um canal de comunicação bidirecional entre dois processos. Ou seja, o canal é composto por duas linhas, uma para falar/escrever e outra para escutar/ler, simultaneamente (modo DUPLEX).

    Note que no programa exemplo vc mesmo fecha a linha de comunicação “que não será usada”. Ora, vc fechou pq quis, se não fechar e for utilizá-la, terá uma comunicação bidirecional entre os processos pai e filho, o que pode ser útil em dados casos.

    Num “pipe” de linha de comando ficaria mais difícil preservar tal possibilidade, pois o programa típico só têm a entrada e saída (têm a saída de erro tb, mas essa não seria uma saída normal), então a saída de um, fica direcionada a entrada do próximo, e assim por diante. Daí talvez as pessoas ficaram achando que o “pipe” usado dentro do programa entre os processos pai e filho, também seria unidirecional, quando não é verdade.

    Na linha de comando:

    prog1 | prog2 | prog3

    Age como:
    teclado > prog1 > progr2 > prog3 > tela

    Já o pipe da programação:
    processo pai > processo filho

    processo pai < processo filho

    • Marcos Souza

      Olá Xinuo,

      verdade, me expressei da forma errada. Quis dizer que o pipe em si só funciona em um sentido: o lado que escreve e o lado que lê.

      Sobre o full-duplex, este somente existe pelo execução do fork, onde o processo filho “herda” do processo pai os fds para o mesmo pipe. E como neste exemplo não teria utilidade dois processos conversarem utilizando o mesmo pipe então decidi fechar como boa prática. Irei falar sobre os pipes executados pelo shell no próximo post, espero que goste!

      Irei melhorar a descrição do funcionamento dos pipes para deixar isto mais claro. Na verdade achei que havia explicado de uma forma clara, mas depois de ver o seu comentário me parece que ficou confuso mesmo. Muito obrigado por ler este post! Espero que você leia a continuação deste e espero muito ver seus comentários!

      Muito obrigado!

      • Xinuo

        Ainda discordo. A função pipe(), presente na biblioteca C, dos SOs do tipo Unix, é FULL-DUPLEX. Os outros pipes (de linha de comando e o arquivo de pipe), é que são SIMPLEX.

        A prova: na chamada pipe(), vc necessariamente passa o fds para ter o canal de leitura e o de escrita. Ter a possibilidade de comunicação entre as duas pontas, é necessário para se ter uma comunicação FULL-DUPLEX. Se não tivesse a possibilidade de uso simultâneo, mas tendo a ida e a volta, então seria uma comunicação HALF-DUPLEX. Já a comunicação SIMPLEX, é o que vc pensa do pipe, uma canal só de ida.

        Note também que vc não precisa do fork() para usar o pipe(), pode ser outra forma de concorrência, ou mesmo ser uma thread só.

        Mas tudo bem, é a minha maneira de ver, a sua maneira é diferente, provavelmente vc vai dizer que a chamada pipe() retorna 2 pipes, um para escrita, outro para leitura, já eu classifico como dois canais.

        • Marcos Souza

          Olá Xinuo, só para fim de complementar o que você disse, segue o man do pipe:

          pipe() creates a pipe, a unidirectional data channel that can be used for interprocess communication. The array pipefd is used to return two file descriptors referring to the ends of the pipe.
          pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe. Data written to the write end of the pipe is buffered by the kernel until it is read from the read end
          of the pipe. For further details, see pipe(7).

          Claro, as vezes temos pontos de vista diferentes, mas me baseiei no man do pipe e no livro The Linux Programming Interface para explicar da forma mais simples que encontrei.

          Acredito que este nosso debate é muito válido para a validade deste artigo! Obrigado novamente pela discussão!

          • Xinuo

            Não interessa o que está escrito nessa man, o que importa, o FATO, é que a chamada possibilita uma forma do processo se comunicar em FULL-DUPLEX com a outra ponta. Então o que está escrito nessa man é contraditório. A man aqui do meu sistema é bem mais técnica e precisa:

            pipe() creates a pair of file descriptors, pointing to a pipe inode, and places them in the array pointed to by filedes. filedes[0] is for reading, filedes[1] is for writing.

            A minha correção para essa man aí do seu sistema seria:

            pipe() creates a pipe, A SET OF TWO unidirectional data channel that can be used for interprocess communication.

          • Marcos Souza

            Quando voce diz “meu sistema”, acredito que você esteja usando algum BSD ou algum outro tipo de *NIX certo? Bom, Aqui estou usando o Fedora 21, e acredito que o man esteja correto.

            Interessante que você fala em “inode”, ou seja, você esta usando um Fifo, que consiste em um objeto no filesystem que faz com que o pipe seja usado por processos não afiliados. Estamos falando sobre o mesmo assunto?

          • Xinuo

            É o seguinte: eu pouco usei essa chamada pipe() e nunca usei essa
            chamada da maneira como teorizei. Tentei usar aqui como FULL-DUPLEX e
            falhei, então vc deve ter razão.

            Então na verdade não é
            FULL-DUPLEX, é SIMPLEX, mas talvez possa ser usada como HALF-DUPLEX se
            vc usar um esquema que eu não teria experiência para implementar, mas
            por uma sincronia que fiz de propósito no meu programa de testes, eu
            consegui que funcionasse. Se vc escreve no fds[1] e lê no fds[0], qq um,
            incluindo a outra ponta, tb pode fazer o mesmo. Mas se não tiver
            cuidado, acabará lendo algo que ele mesmo (o processo) colocou no pipe.

          • Marcos Souza

            Você está usando algum BSD ou algo do tipo? No caso de outros *NIX existe o “stream pipe” como descrito The Linux Progromming Interface:

            “Data can travel only in one direction through a pipe. One end of the pipe is used
            for writing, and the other end is used for reading.
            On some other UNIX implementations—notably those derived from System V
            Release 4—pipes are bidirectional (so-called stream pipes). Bidirectional pipes are
            not specified by any UNIX standards, so that, even on implementations where they
            are provided, it is best to avoid reliance on their semantics. As an alternative, we
            can use UNIX domain stream socket pairs (created using the socketpair() system call
            described in Section 57.5), which provide a standardized bidirectional communi-
            cation mechanism that is semantically equivalent to stream pipes.”

            Este é o seu caso?

        • Guest

          É o seguinte: eu pouco usei essa chamada pipe() e nunca usei essa chamada da maneira como teorizei. Tentei usar aqui como FULL-DUPLEX e falhei, então vc deve ter razão.

          Então na verdade não é FULL-DUPLEX, é SIMPLEX, mas talvez possa ser usada como HALF-DUPLEX se vc usar um esquema que eu não teria experiência para implementar, mas por uma sincronia que fiz de propósito no meu programa de testes, eu consegui que funcionasse. Se vc escreve no fds[1] e lê no fds[0], qq um, incluindo a outra ponta, tb pode fazer o mesmo. Mas se não tiver cuidado, acabará lendo algo que ele mesmo colocou no pipe.

  • Xinuo

    Pipes NÃO são como canos que unem os processos unidirecionalmente, como vc afirmou. Pense assim: num cano, algo que passa nele, também pode voltar. Se pensar em cachimbo da paz, pense no índio que lhe dá o cachimbo para dar uma tragada, vc passa ele de volta e depois da tragada dele, ele passa de volta para vc, e assim vai.

    Então eu digo: “pipes” são como chamadas telefônicas, que abrem um canal de comunicação bidirecional entre dois processos. Ou seja, o canal é composto por duas linhas, uma para falar/escrever e outra para escutar/ler, simultaneamente (modo DUPLEX).

    Note que no programa exemplo vc mesmo fecha a linha de comunicação “que não será usada”. Ora, vc fechou pq quis, se não fechar e for utilizá-la, terá uma comunicação bidirecional entre os processos pai e filho, o que pode ser útil em dados casos.

    Num “pipe” de linha de comando ficaria mais difícil preservar tal possibilidade, pois o programa típico só têm a entrada e saída (têm a saída de erro tb, mas essa não seria uma saída normal), então a saída de um, fica direcionada a entrada do próximo, e assim por diante. Daí talvez as pessoas ficaram achando que o “pipe” usado dentro do programa entre os processos pai e filho, também seria unidirecional, quando não é verdade.

    Na linha de comando:

    prog1 | prog2 | prog3

    Age como:
    teclado > prog1 > progr2 > prog3 > tela

    Já o pipe da programação:
    processo pai > processo filho

    processo pai < processo filho

    • Marcos Souza

      Olá Xinuo,

      verdade, me expressei da forma errada. Quis dizer que o pipe em si só funciona em um sentido: o lado que escreve e o lado que lê.

      Sobre o full-duplex, este somente existe pelo execução do fork, onde o processo filho “herda” do processo pai os fds para o mesmo pipe. E como neste exemplo não teria utilidade dois processos conversarem utilizando o mesmo pipe então decidi fechar como boa prática. Irei falar sobre os pipes executados pelo shell no próximo post, espero que goste!

      Irei melhorar a descrição do funcionamento dos pipes para deixar isto mais claro. Na verdade achei que havia explicado de uma forma clara, mas depois de ver o seu comentário me parece que ficou confuso mesmo. Muito obrigado por ler este post! Espero que você leia a continuação deste e espero muito ver seus comentários!

      Muito obrigado!

      • Xinuo

        Ainda discordo. A função pipe(), presente na biblioteca C, dos SOs do tipo Unix, é FULL-DUPLEX. Os outros pipes (de linha de comando e o arquivo de pipe), é que são SIMPLEX.

        A prova: na chamada pipe(), vc necessariamente passa o fds para ter o canal de leitura e o de escrita. Ter a possibilidade de comunicação entre as duas pontas, é necessário para se ter uma comunicação FULL-DUPLEX. Se não tivesse a possibilidade de uso simultâneo, mas tendo a ida e a volta, então seria uma comunicação HALF-DUPLEX. Já a comunicação SIMPLEX, é o que vc pensa do pipe, uma canal só de ida.

        Note também que vc não precisa do fork() para usar o pipe(), pode ser outra forma de concorrência, ou mesmo ser uma thread só.

        Mas tudo bem, é a minha maneira de ver, a sua maneira é diferente, provavelmente vc vai dizer que a chamada pipe() retorna 2 pipes, um para escrita, outro para leitura, já eu classifico como dois canais.

        • Marcos Souza

          Olá Xinuo, só para fim de complementar o que você disse, segue o man do pipe:

          pipe() creates a pipe, a unidirectional data channel that can be used for interprocess communication. The array pipefd is used to return two file descriptors referring to the ends of the pipe.
          pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe. Data written to the write end of the pipe is buffered by the kernel until it is read from the read end
          of the pipe. For further details, see pipe(7).

          Claro, as vezes temos pontos de vista diferentes, mas me baseiei no man do pipe e no livro The Linux Programming Interface para explicar da forma mais simples que encontrei.

          Acredito que este nosso debate é muito válido para a validade deste artigo! Obrigado novamente pela discussão!

          • Xinuo

            Não interessa o que está escrito nessa man, o que importa, o FATO, é que a chamada possibilita uma forma do processo se comunicar em FULL-DUPLEX com a outra ponta. Então o que está escrito nessa man é contraditório. A man aqui do meu sistema é bem mais técnica e precisa:

            pipe() creates a pair of file descriptors, pointing to a pipe inode, and places them in the array pointed to by filedes. filedes[0] is for reading, filedes[1] is for writing.

            A minha correção para essa man aí do seu sistema seria:

            pipe() creates a pipe, A SET OF TWO unidirectional data channel that can be used for interprocess communication.

          • Marcos Souza

            Quando voce diz “meu sistema”, acredito que você esteja usando algum BSD ou algum outro tipo de *NIX certo? Bom, Aqui estou usando o Fedora 21, e acredito que o man esteja correto.

            Interessante que você fala em “inode”, ou seja, você esta usando um Fifo, que consiste em um objeto no filesystem que faz com que o pipe seja usado por processos não afiliados. Estamos falando sobre o mesmo assunto?

          • Xinuo

            É o seguinte: eu pouco usei essa chamada pipe() e nunca usei essa
            chamada da maneira como teorizei. Tentei usar aqui como FULL-DUPLEX e
            falhei, então vc deve ter razão.

            Então na verdade não é
            FULL-DUPLEX, é SIMPLEX, mas talvez possa ser usada como HALF-DUPLEX se
            vc usar um esquema que eu não teria experiência para implementar, mas
            por uma sincronia que fiz de propósito no meu programa de testes, eu
            consegui que funcionasse. Se vc escreve no fds[1] e lê no fds[0], qq um,
            incluindo a outra ponta, tb pode fazer o mesmo. Mas se não tiver
            cuidado, acabará lendo algo que ele mesmo (o processo) colocou no pipe.

          • Marcos Souza

            Você está usando algum BSD ou algo do tipo? No caso de outros *NIX existe o “stream pipe” como descrito The Linux Progromming Interface:

            “Data can travel only in one direction through a pipe. One end of the pipe is used
            for writing, and the other end is used for reading.
            On some other UNIX implementations—notably those derived from System V
            Release 4—pipes are bidirectional (so-called stream pipes). Bidirectional pipes are
            not specified by any UNIX standards, so that, even on implementations where they
            are provided, it is best to avoid reliance on their semantics. As an alternative, we
            can use UNIX domain stream socket pairs (created using the socketpair() system call
            described in Section 57.5), which provide a standardized bidirectional communi-
            cation mechanism that is semantically equivalent to stream pipes.”

            Este é o seu caso?

        • Guest

          É o seguinte: eu pouco usei essa chamada pipe() e nunca usei essa chamada da maneira como teorizei. Tentei usar aqui como FULL-DUPLEX e falhei, então vc deve ter razão.

          Então na verdade não é FULL-DUPLEX, é SIMPLEX, mas talvez possa ser usada como HALF-DUPLEX se vc usar um esquema que eu não teria experiência para implementar, mas por uma sincronia que fiz de propósito no meu programa de testes, eu consegui que funcionasse. Se vc escreve no fds[1] e lê no fds[0], qq um, incluindo a outra ponta, tb pode fazer o mesmo. Mas se não tiver cuidado, acabará lendo algo que ele mesmo colocou no pipe.

  • Xinuo

    Pipes NÃO são como canos que unem os processos unidirecionalmente, como vc afirmou. Pense assim: num cano, algo que passa nele, também pode voltar. Se pensar em cachimbo da paz, pense no índio que lhe dá o cachimbo para dar uma tragada, vc passa ele de volta e depois da tragada dele, ele passa de volta para vc, e assim vai.

    Então eu digo: “pipes” são como chamadas telefônicas, que abrem um canal de comunicação bidirecional entre dois processos. Ou seja, o canal é composto por duas linhas, uma para falar/escrever e outra para escutar/ler, simultaneamente (modo DUPLEX).

    Note que no programa exemplo vc mesmo fecha a linha de comunicação “que não será usada”. Ora, vc fechou pq quis, se não fechar e for utilizá-la, terá uma comunicação bidirecional entre os processos pai e filho, o que pode ser útil em dados casos.

    Num “pipe” de linha de comando ficaria mais difícil preservar tal possibilidade, pois o programa típico só têm a entrada e saída (têm a saída de erro tb, mas essa não seria uma saída normal), então a saída de um, fica direcionada a entrada do próximo, e assim por diante. Daí talvez as pessoas ficaram achando que o “pipe” usado dentro do programa entre os processos pai e filho, também seria unidirecional, quando não é verdade.

    Na linha de comando:

    prog1 | prog2 | prog3

    Age como:
    teclado > prog1 > progr2 > prog3 > tela

    Já o pipe da programação:
    processo pai > processo filho

    processo pai < processo filho

    • Marcos Souza

      Olá Xinuo,

      verdade, me expressei da forma errada. Quis dizer que o pipe em si só funciona em um sentido: o lado que escreve e o lado que lê.

      Sobre o full-duplex, este somente existe pelo execução do fork, onde o processo filho “herda” do processo pai os fds para o mesmo pipe. E como neste exemplo não teria utilidade dois processos conversarem utilizando o mesmo pipe então decidi fechar como boa prática. Irei falar sobre os pipes executados pelo shell no próximo post, espero que goste!

      Irei melhorar a descrição do funcionamento dos pipes para deixar isto mais claro. Na verdade achei que havia explicado de uma forma clara, mas depois de ver o seu comentário me parece que ficou confuso mesmo. Muito obrigado por ler este post! Espero que você leia a continuação deste e espero muito ver seus comentários!

      Muito obrigado!

      • Xinuo

        Ainda discordo. A função pipe(), presente na biblioteca C, dos SOs do tipo Unix, é FULL-DUPLEX. Os outros pipes (de linha de comando e o arquivo de pipe), é que são SIMPLEX.

        A prova: na chamada pipe(), vc necessariamente passa o fds para ter o canal de leitura e o de escrita. Ter a possibilidade de comunicação entre as duas pontas, é necessário para se ter uma comunicação FULL-DUPLEX. Se não tivesse a possibilidade de uso simultâneo, mas tendo a ida e a volta, então seria uma comunicação HALF-DUPLEX. Já a comunicação SIMPLEX, é o que vc pensa do pipe, uma canal só de ida.

        Note também que vc não precisa do fork() para usar o pipe(), pode ser outra forma de concorrência, ou mesmo ser uma thread só.

        Mas tudo bem, é a minha maneira de ver, a sua maneira é diferente, provavelmente vc vai dizer que a chamada pipe() retorna 2 pipes, um para escrita, outro para leitura, já eu classifico como dois canais.

        • Marcos Souza

          Olá Xinuo, só para fim de complementar o que você disse, segue o man do pipe:

          pipe() creates a pipe, a unidirectional data channel that can be used for interprocess communication. The array pipefd is used to return two file descriptors referring to the ends of the pipe.
          pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe. Data written to the write end of the pipe is buffered by the kernel until it is read from the read end
          of the pipe. For further details, see pipe(7).

          Claro, as vezes temos pontos de vista diferentes, mas me baseiei no man do pipe e no livro The Linux Programming Interface para explicar da forma mais simples que encontrei.

          Acredito que este nosso debate é muito válido para a validade deste artigo! Obrigado novamente pela discussão!

          • Xinuo

            Não interessa o que está escrito nessa man, o que importa, o FATO, é que a chamada possibilita uma forma do processo se comunicar em FULL-DUPLEX com a outra ponta. Então o que está escrito nessa man é contraditório. A man aqui do meu sistema é bem mais técnica e precisa:

            pipe() creates a pair of file descriptors, pointing to a pipe inode, and places them in the array pointed to by filedes. filedes[0] is for reading, filedes[1] is for writing.

            A minha correção para essa man aí do seu sistema seria:

            pipe() creates a pipe, A SET OF TWO unidirectional data channel that can be used for interprocess communication.

          • Marcos Souza

            Quando voce diz “meu sistema”, acredito que você esteja usando algum BSD ou algum outro tipo de *NIX certo? Bom, Aqui estou usando o Fedora 21, e acredito que o man esteja correto.

            Interessante que você fala em “inode”, ou seja, você esta usando um Fifo, que consiste em um objeto no filesystem que faz com que o pipe seja usado por processos não afiliados. Estamos falando sobre o mesmo assunto?

          • Xinuo

            É o seguinte: eu pouco usei essa chamada pipe() e nunca usei essa
            chamada da maneira como teorizei. Tentei usar aqui como FULL-DUPLEX e
            falhei, então vc deve ter razão.

            Então na verdade não é
            FULL-DUPLEX, é SIMPLEX, mas talvez possa ser usada como HALF-DUPLEX se
            vc usar um esquema que eu não teria experiência para implementar, mas
            por uma sincronia que fiz de propósito no meu programa de testes, eu
            consegui que funcionasse. Se vc escreve no fds[1] e lê no fds[0], qq um,
            incluindo a outra ponta, tb pode fazer o mesmo. Mas se não tiver
            cuidado, acabará lendo algo que ele mesmo (o processo) colocou no pipe.

          • Marcos Souza

            Você está usando algum BSD ou algo do tipo? No caso de outros *NIX existe o “stream pipe” como descrito The Linux Progromming Interface:

            “Data can travel only in one direction through a pipe. One end of the pipe is used
            for writing, and the other end is used for reading.
            On some other UNIX implementations—notably those derived from System V
            Release 4—pipes are bidirectional (so-called stream pipes). Bidirectional pipes are
            not specified by any UNIX standards, so that, even on implementations where they
            are provided, it is best to avoid reliance on their semantics. As an alternative, we
            can use UNIX domain stream socket pairs (created using the socketpair() system call
            described in Section 57.5), which provide a standardized bidirectional communi-
            cation mechanism that is semantically equivalent to stream pipes.”

            Este é o seu caso?

        • Guest

          É o seguinte: eu pouco usei essa chamada pipe() e nunca usei essa chamada da maneira como teorizei. Tentei usar aqui como FULL-DUPLEX e falhei, então vc deve ter razão.

          Então na verdade não é FULL-DUPLEX, é SIMPLEX, mas talvez possa ser usada como HALF-DUPLEX se vc usar um esquema que eu não teria experiência para implementar, mas por uma sincronia que fiz de propósito no meu programa de testes, eu consegui que funcionasse. Se vc escreve no fds[1] e lê no fds[0], qq um, incluindo a outra ponta, tb pode fazer o mesmo. Mas se não tiver cuidado, acabará lendo algo que ele mesmo colocou no pipe.

  • Rodrigo Vinicius Mendonca Pere

    Muito interessante o assunto e parabéns pelo conteúdo escrito. Poderia sugerir entretanto que o código fosse um pouco mais comentado, de forma a fazer um link com o que foi escrito. Senti um pouco de dificuldade a partir do 4 parágrafo. Mais uma vez parabéns.

    • Marcos Souza

      Olá Rodrigo, que bom que você gostou!

      Coloquei mais uns comentários, verifique se ajudou no entendimento do código! Um abraço!

  • Rodrigo Vinicius Mendonca Pere

    Muito interessante o assunto e parabéns pelo conteúdo escrito. Poderia sugerir entretanto que o código fosse um pouco mais comentado, de forma a fazer um link com o que foi escrito. Senti um pouco de dificuldade a partir do 4 parágrafo. Mais uma vez parabéns.

    • Marcos Souza

      Olá Rodrigo, que bom que você gostou!

      Coloquei mais uns comentários, verifique se ajudou no entendimento do código! Um abraço!

  • Rodrigo Vinicius Mendonca Pere

    Muito interessante o assunto e parabéns pelo conteúdo escrito. Poderia sugerir entretanto que o código fosse um pouco mais comentado, de forma a fazer um link com o que foi escrito. Senti um pouco de dificuldade a partir do 4 parágrafo. Mais uma vez parabéns.

    • Marcos Souza

      Olá Rodrigo, que bom que você gostou!

      Coloquei mais uns comentários, verifique se ajudou no entendimento do código! Um abraço!