Compartilhar via


_pipe

Cria um pipe para ler e gravar.

Observação importanteImportante

Este API não pode ser usado em aplicativos executados em Tempo de Execução do Windows.Para obter mais informações, consulte Funções de CRT não suportadas com /ZW.

int _pipe( int *pfds, unsigned int psize, int textmode );

Parâmetros

  • pfds[2]
    Matriz para armazenar a leitura e gravação descritores de arquivo.

  • psize
    Quantidade de memória para a reserva.

  • textmode
    Modo de Arquivo.

Valor de retorno

Retorna 0 se com êxito.Retorna – 1 para indicar um erro.No erro, errno é definida como um desses valores:

  • EMFILE, que indica que não mais arquivo descritor está disponível.

  • ENFILE, que indica um estouro de sistema-Arquivo- tabela.

  • EINVAL, que indica que a matriz pfds é um ponteiro zero ou que um valor inválido para textmode esteve passado.

Para obter mais informações sobre esses e outros códigos de retorno, consulte errno, _doserrno, _sys_errlist e _sys_nerr.

Comentários

A função de _pipe cria um pipe, que é um canal de E/S que artificialmente um programa usa para passar informações para outros programas.Um pipe é semelhante a um arquivo porque tem um ponteiro de arquivo, um arquivo descritor, ou ambos, e pode ser lido ou gravado da usar as funções padrão de entrada e saída da biblioteca.No entanto, um pipe não representa um arquivo ou um dispositivo específico.Em vez disso, representa o armazenamento temporário na memória que é independente de própria memória do programa e é inteiramente controlado pelo sistema operacional.

_pipe é semelhante a _open mas abre-se o pipe para ler e gravar e retorna dois descritores de arquivo em vez de um.O programa pode usar ambos os lados de pipe ou fechar o que não precisa.Por exemplo, o processador de comando no Windows cria um pipe quando executa um comando como PROGRAM1 | PROGRAM2.

O descritor padrão de saída de PROGRAM1 é anexado ao descritor de gravação de pipe.O descritor padrão de entrada de PROGRAM2 é anexado ao descritor de leitura de pipe.Isso elimina a necessidade de criar arquivos temporários para passar informações para outros programas.

A função de _pipe returna dois descritores de arquivo para o pipe no argumento de pfds .O elemento 0 pfds[] contém o descritor de leitura, e o elemento 1 pfds[] contém o descritor de gravação.Descritores de arquivo de pipe são utilizados da mesma maneira que outros descritores de arquivo.(As funções de baixo nível _read e _write de entrada e saída podem ler e escrever em um pipe.) Para detectar a condição no final do ciclo, verificar uma solicitação de _read que retorna 0 como o número de bytes.

O argumento de psize especifica a quantidade de memória, em bytes, para reservar o pipe.O argumento de textmode especifica o modo de tradução para o pipe._O_TEXT constante manifesto especifica uma conversão de texto, e _O_BINARY constante especifica a conversão binário.(Consulte fopen, _wfopen para obter uma descrição de modos de texto e de binário.) Se o argumento de textmode é 0, _pipe usar o modo padrão de conversão que é especificado pela variável _fmodede modo padrão.

Em programas multi-thread, nenhum bloqueio é executado.Descritores de arquivo que são retornados recentemente estão abertos e não devem ser referenciados por qualquer segmento até após a chamada de _pipe concluída.

Para usar a função de _pipe para se comunicar entre um processo pai e um processo filho, cada processo deve ter apenas um descritor aberto no pipe.Descritores devem ser opostos: se o pai tiver um descritor de leitura aberto, então o filho deve ter um descritor de gravação aberto.A maneira mais fácil para fazer isso é a OR (|o sinalizador) de _O_NOINHERIT com textmode.Em seguida, use _dup ou _dup2 criar uma cópia herdável de descritor de pipe que você deseja passar para o filho.Feche o descritor original, e desovar no processo filho.O retorno de chamada de ova, feche o descritor duplicado no processo pai.Para mais informações, consulte o exemplo neste artigo 2 posteriormente.

No sistema operacional Windows, um pipe é destruído quando todos os seus descritores foram fechados.(Se todos os descritores no pipe foram fechados, então gravação para o pipe causa um erro.) Todas as operações de leitura e gravação no pipe espera até que haja suficiente dados ou espaço suficiente de buffer para concluir a solicitação de E/S.

Requisitos

Rotina

Cabeçalho necessário

Cabeçalho opcional

_pipe

<io.h>

<fcntl.h>, 1 <errno.h>2

1 Para _O_BINARY e definições de _O_TEXT .

2 definições de errno .

Para mais informações, consulte Compatibilidadede compatibilidade.

Bibliotecas

Todas as versões de Bibliotecas em tempo de execução de C.

Exemplo 1

// crt_pipe.c
/* This program uses the _pipe function to pass streams of
 * text to spawned processes.
 */

#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <process.h>
#include <math.h>

enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */
#define NUMPROBLEM 8

int main( int argc, char *argv[] )
{

   int fdpipe[2];
   char hstr[20];
   int pid, problem, c;
   int termstat;

   /* If no arguments, this is the spawning process */
   if( argc == 1 )
   {

      setvbuf( stdout, NULL, _IONBF, 0 );

      /* Open a set of pipes */
      if( _pipe( fdpipe, 256, O_BINARY ) == -1 )
          exit( 1 );


      /* Convert pipe read descriptor to string and pass as argument 
       * to spawned program. Program spawns itself (argv[0]).
       */
      _itoa_s( fdpipe[READ], hstr, sizeof(hstr), 10 );
      if( ( pid = _spawnl( P_NOWAIT, argv[0], argv[0], 
            hstr, NULL ) ) == -1 )
          printf( "Spawn failed" );

      /* Put problem in write pipe. Since spawned program is 
       * running simultaneously, first solutions may be done 
       * before last problem is given.
       */
      for( problem = 1000; problem <= NUMPROBLEM * 1000; problem += 1000)
      {

         printf( "Son, what is the square root of %d?\n", problem );
         _write( fdpipe[WRITE], (char *)&problem, sizeof( int ) );

      }

      /* Wait until spawned program is done processing. */
      _cwait( &termstat, pid, WAIT_CHILD );
      if( termstat & 0x0 )
         printf( "Child failed\n" );


      _close( fdpipe[READ] );
      _close( fdpipe[WRITE] );

   }

   /* If there is an argument, this must be the spawned process. */
   else
   {

      /* Convert passed string descriptor to integer descriptor. */
      fdpipe[READ] = atoi( argv[1] );

      /* Read problem from pipe and calculate solution. */
      for( c = 0; c < NUMPROBLEM; c++ )
      {

        _read( fdpipe[READ], (char *)&problem, sizeof( int ) );
        printf( "Dad, the square root of %d is %3.2f.\n",
                 problem, sqrt( ( double )problem ) );

      }
   }
}

A saída de exemplo

Son, what is the square root of 1000?
Son, what is the square root of 2000?
Son, what iDad, the square root of 1000 is 31.62.
Dad, the square root of 2000 is 44.72.
s the square root of 3000?
Dad, the square root of 3000 is 54.77.
Son, what is the square root of 4000?
Dad, the square root of 4000 is 63.25.
Son, what is the square root of 5000?
Dad, the square root of 5000 is 70.71.
Son, what is the square root of 6000?
SonDad, the square root of 6000 is 77.46.
, what is the square root of 7000?
Dad, the square root of 7000 is 83.67.
Son, what is the square root of 8000?
Dad, the square root of 8000 is 89.44.

Exemplo 2

Este é um aplicativo básico de filtro.Desova o crt_pipe_beeper do aplicativo depois que cria um pipe que direciona o stdout do aplicativo desovado para o filtro.O filtro remove caracteres ASCII 7 (do bipe).

// crt_pipe_beeper.c

#include <stdio.h>
#include <string.h>

int main()
{
   int   i;
   for(i=0;i<10;++i)
      {
         printf("This is speaker beep number %d...\n\7", i+1);
      }
   return 0;
}

O aplicativo real de filtro:

// crt_pipe_BeepFilter.C
// arguments: crt_pipe_beeper.exe

#include <windows.h>
#include <process.h>
#include <memory.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>

#define   OUT_BUFF_SIZE 512
#define   READ_FD 0
#define   WRITE_FD 1
#define   BEEP_CHAR 7

char szBuffer[OUT_BUFF_SIZE];

int Filter(char* szBuff, ULONG nSize, int nChar)
{
   char* szPos = szBuff + nSize -1;
   char* szEnd = szPos;
   int nRet = nSize;

   while (szPos > szBuff)
   {
      if (*szPos == nChar)
         {
            memmove(szPos, szPos+1, szEnd - szPos);
            --nRet;
         }
      --szPos;
   }
   return nRet;
}

int main(int argc, char** argv)
{
   int nExitCode = STILL_ACTIVE;
   if (argc >= 2)
   {
      HANDLE hProcess;
      int fdStdOut;
      int fdStdOutPipe[2];

      // Create the pipe
      if(_pipe(fdStdOutPipe, 512, O_NOINHERIT) == -1)
         return   1;

      // Duplicate stdout file descriptor (next line will close original)
      fdStdOut = _dup(_fileno(stdout));

      // Duplicate write end of pipe to stdout file descriptor
      if(_dup2(fdStdOutPipe[WRITE_FD], _fileno(stdout)) != 0)
         return   2;

      // Close original write end of pipe
      _close(fdStdOutPipe[WRITE_FD]);

      // Spawn process
      hProcess = (HANDLE)_spawnvp(P_NOWAIT, argv[1], 
       (const char* const*)&argv[1]);

      // Duplicate copy of original stdout back into stdout
      if(_dup2(fdStdOut, _fileno(stdout)) != 0)
         return   3;

      // Close duplicate copy of original stdout
      _close(fdStdOut);

      if(hProcess)
      {
         int nOutRead;
         while   (nExitCode == STILL_ACTIVE)
         {
            nOutRead = _read(fdStdOutPipe[READ_FD], 
             szBuffer, OUT_BUFF_SIZE);
            if(nOutRead)
            {
               nOutRead = Filter(szBuffer, nOutRead, BEEP_CHAR);
               fwrite(szBuffer, 1, nOutRead, stdout);
            }

            if(!GetExitCodeProcess(hProcess,(unsigned long*)&nExitCode))
               return 4;
         }
      }
   }
   return nExitCode;
}

Saída

This is speaker beep number 1...
This is speaker beep number 2...
This is speaker beep number 3...
This is speaker beep number 4...
This is speaker beep number 5...
This is speaker beep number 6...
This is speaker beep number 7...
This is speaker beep number 8...
This is speaker beep number 9...
This is speaker beep number 10...

Equivalência do .NET Framework

Não aplicável. Para chamar a função padrão de C, use PInvoke. Para obter mais informações, consulte Exemplos de invocação de plataforma.

Consulte também

Referência

Processo e controle do ambiente

Open, _wopen