Compartir a través de


_pipe

Crea una canalización para leer y escribir.

Nota importanteImportante

Esta API no se puede utilizar en las aplicaciones que se ejecutan en Windows en tiempo de ejecución.Para obtener más información, vea Funciones CRT no compatibles con /ZW.

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

Parámetros

  • pfds[2]
    Matriz para contener descriptores de archivo de lectura y escritura.

  • psize
    Cantidad de memoria para reservar.

  • textmode
    Modo de acceso al archivo.

Valor devuelto

Devuelve 0 si correctamente.Devuelve – 1 para indicar un error.Por error, errno se establece en uno de estos valores:

  • EMFILE, que indica que no más de descriptores de archivo están disponibles.

  • ENFILE, que indica un desbordamiento de la sistema-archivo-tabla.

  • EINVAL, que indica que la matriz pfds es un puntero NULL o que un valor no válido para textmode se ha pasado.

Para obtener más información sobre éstos y otros códigos de retorno, vea errno, _doserrno, _sys_errlist, y _sys_nerr.

Comentarios

La función de _pipe crea una canalización, un canal de E/S artificial que un programa utiliza para pasar información a otros programas.Una canalización se parece a un archivo porque tiene un puntero de archivo, descriptor de archivo, o ambos, y se puede leer de o escriba a la entrada y la salida estándar de biblioteca funciona.Sin embargo, una canalización no representa un archivo específico o un dispositivo.En su lugar, representa desbordamiento en memoria que es independiente de propia memoria del programa y está controlada por completo del sistema operativo.

_pipe se parece a _open pero abre la canalización para leer y escribir y devuelve dos descriptores de archivo en lugar de uno.El programa puede utilizar ambos extremos de la canalización o cerrar la que no necesita.Por ejemplo, el procesador de comandos de Windows crea una canalización cuando ejecuta un comando como PROGRAM1 | PROGRAM2.

Asociados a la salida descriptor del estándar de PROGRAM1 a escribir descriptor de la canalización.La entrada estándar descriptor de PROGRAM2 se adjunta a la lectura descriptor de la canalización.Esto elimina la necesidad de crear archivos temporales para pasar información a otros programas.

La función de _pipe devuelve dos descriptores de archivo en la canalización en el argumento de pfds.El elemento pfds[0] contiene la lectura descriptor, y el elemento pfds[1] contiene la escritura descriptor.Utilizan descriptores de archivo de la canalización igual que otros descriptores de archivo.(Las funciones de bajo nivel _read y _write de entrada y salida se pueden leer y escribir en una canalización.) Para detectar la condición de tubo terminal, comprobación de una solicitud de _read que devuelve 0 como número de bytes leídos.

El argumento de psize especifica la cantidad de memoria, en bytes, para reservar para la canalización.El argumento de textmode especifica el de modalidad de traducción de la canalización._O_TEXT constante manifiesto especifica una traducción de texto, y _O_BINARY constante especifica la traducción binaria.(Vea fopen, _wfopen para obtener una descripción de los modos de texto y binario.) Si el argumento de textmode es 0, _pipe utiliza el de modalidad de traducción predeterminado especificado por la variable _fmode de valor por defecto- modo.

En programas multiproceso, no se realiza ningún bloqueo.Abra y no deben hacer referencia a los descriptores de archivo que se devuelven recientemente por ningún subproceso hasta que se complete la llamada de _pipe.

Para utilizar la función de _pipe para comunicarse entre un proceso primario y un proceso secundario, cada proceso solo debe tener un descriptor abierto en la canalización.Descriptores deben ser de contadores: si el elemento primario tiene una lectura descriptor abierto, el elemento secundario debe tener una escritura descriptor abierto.La manera más fácil de hacer esto se OR (|) el indicador de _O_NOINHERIT con textmode.A continuación, utilice _dup o _dup2 de crear una copia heredable de canalización descriptor que desea pasar al elemento secundario.Cierre descriptor original, y después generar el proceso secundario.Al volver de la llamada al generar, cierre descriptor duplicado en el proceso primario.Para obtener más información, vea el ejemplo 2 más adelante en este artículo.

En el sistema operativo Windows, se destruye una canalización cuando se han cerrado todos sus descriptores.(Si se han cerrado todos los descriptores de lectura en la canalización, la escritura a la canalización produce un error). Todas las operaciones de lectura y escritura en la canalización esperan hasta que haya suficientes datos o suficiente espacio en búfer para completar la solicitud de E/S.

Requisitos

Rutina

Encabezado necesario

Encabezado opcional

_pipe

<io.h>

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

1 Para _O_BINARY y definiciones de _O_TEXT.

2 definiciones de errno.

Para obtener más información de compatibilidad, vea Compatibilidad.

Bibliotecas

Todas las versiones de Bibliotecas en tiempo de ejecución de C.

Ejemplo 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 ) );

      }
   }
}

Resultados del ejemplo

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.

Ejemplo 2

Esta es una aplicación básica de filtro.Generar el crt_pipe_beeper de la aplicación después de crear una canalización que dirige el stdout de aplicación todos los generada al filtro.El filtro quita los 7 caracteres ASCII (beep).

// 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;
}

La aplicación 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;
}

Output

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...

Equivalente en .NET Framework

No es aplicable Para llamar a la función estándar de C, utilice PInvoke. Para obtener más información, vea Ejemplos de invocación de plataforma.

Vea también

Referencia

Proceso y control ambiental

_open, _wopen