Sdílet prostřednictvím


_pipe

Vytvoří kanál pro čtení a zápis.

Důležité

Toto rozhraní API nelze použít v aplikacích, které se spouští v prostředí Windows Runtime. Další informace najdete v tématu Funkce CRT, které nejsou v aplikacích Univerzální platforma Windows podporované.

Syntaxe

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

Parametry

pfds
Ukazatel na pole dvou int pro uložení popisovačů souboru pro čtení a zápis.

psize
Množství paměti, které je potřeba rezervovat.

textmode
Režim souborů.

Vrácená hodnota

Vrátí hodnotu 0, pokud je úspěšná. Vrátí hodnotu -1, která označuje chybu. Při chybě errno je nastavená jedna z těchto hodnot:

  • EMFILE, což znamená, že nejsou k dispozici žádné další popisovače souborů.

  • ENFILE, který označuje přetečení systémové tabulky souborů.

  • EINVAL, což označuje, že pole pfds je ukazatel null nebo že byla předána neplatná hodnota pro textmode .

Další informace o těchto a dalších návratových kódech naleznete v tématu , , , a_sys_nerr . _sys_errlist_doserrnoerrno

Poznámky

Funkce _pipe vytvoří kanál, což je umělý vstupně-výstupní kanál, který program používá k předávání informací jiným programům. Kanál se podobá souboru, protože má ukazatel souboru, popisovač souboru nebo obojí. A dá se načíst z nebo zapsat pomocí vstupních a výstupních funkcí standardní knihovny. Kanál ale nepředstavuje konkrétní soubor ani zařízení. Místo toho představuje dočasné úložiště v paměti, které je nezávislé na vlastní paměti programu a je řízeno zcela operačním systémem.

_pipe_open podobá se, ale otevře kanál pro čtení a zápis a vrátí dva popisovače souborů místo jednoho. Program může použít obě strany potrubí nebo zavřít tu, kterou nepotřebuje. Například procesor příkazů ve Windows vytvoří kanál při spuštění příkazu, například PROGRAM1 | PROGRAM2.

Standardní popisovač výstupu PROGRAM1 je připojen k popisovači zápisu potrubí. Standardní vstupní popisovač PROGRAM2 je připojen k popisovači čtení potrubí. Tato příloha eliminuje potřebu vytvářet dočasné soubory pro předávání informací jiným programům.

Funkce _pipe vrátí dva popisovače souboru do potrubí v argumentu pfds . Element pfds[0] obsahuje popisovač pro čtení a element pfds[1] obsahuje popisovač zápisu. Popisovače souborů potrubí se používají stejným způsobem jako jiné popisovače souborů. (Vstupní a výstupní funkce _read nízké úrovně a _write mohou číst z kanálu a zapisovat do kanálu.) Pokud chcete zjistit stav konce kanálu, zkontrolujte _read požadavek, který vrací hodnotu 0 jako počet přečtených bajtů.

Argument psize určuje velikost paměti v bajtech, která se má pro kanál rezervovat. Argument textmode určuje režim překladu kanálu. Konstanta _O_TEXT manifestu určuje překlad textu ANSI a konstanta _O_BINARY určuje binární překlad. (Viz fopen_wfopen popis textového a binárního režimu.) textmode Pokud je argument 0, _pipe použije výchozí režim překladu určený proměnnou _fmodevýchozího režimu .

Ve vícevláknových programech se neprovádí žádné uzamčení. Vrácené popisovače souborů jsou nově otevřené a neměly by na ni odkazovat žádné vlákno, dokud _pipe se volání nedokončí.

Aby bylo možné pomocí _pipe funkce komunikovat mezi nadřazeným a podřízeným procesem, musí mít každý proces na kanálu otevřený pouze jeden popisovač. Popisovače musí být opačné: pokud má nadřazený popisovač otevřený popisovač čtení, musí mít podřízený popisovač otevřený popisovač zápisu. Nejjednodušší je použít bitové "or" (|) na příznaku _O_NOINHERIT s textmode. Potom použijte _dup nebo _dup2 vytvořte zděděnou kopii popisovače kanálu, kterou chcete předat podřízené sadě. Zavřete původní popisovač a potom podřízený proces vytvoříte. Při návratu z volání spawn zavřete duplicitní popisovač v nadřazeného procesu. Další informace najdete v příkladu 2 dále v tomto článku.

V operačním systému Windows je potrubí zničeno, když jsou všechny jeho popisovače uzavřeny. (Pokud jsou všechny popisovače pro čtení na kanálu zavřené, pak zápis do kanálu způsobí chybu.) Všechny operace čtení a zápisu na kanálu čekají, dokud není dostatek dat nebo dostatek místa na vyrovnávací paměti pro dokončení V/V požadavku.

Ve výchozím nastavení je globální stav této funkce vymezen na aplikaci. Chcete-li toto chování změnit, přečtěte si téma Globální stav v CRT.

Požadavky

Rutina Požadovaný hlavičkový soubor Volitelné záhlaví
_pipe <io.h> <fcntl.h>,1<errno.h>2

1 Pro _O_BINARY a _O_TEXT definice.

2errno definice.

Další informace o kompatibilitě najdete v tématu Kompatibilita.

Knihovny

Všechny verze knihoven runtime jazyka C.

Příklad 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 ) );

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

Příklad 2

Ukázkový kód je základní aplikace filtru. Vytvoří aplikaci crt_pipe_beeper poté, co vytvoří kanál, který nasměruje vytvořenou aplikaci stdout do filtru. Filtr odebere znaky ASCII 7 (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;
}

Skutečná aplikace filtru:

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

Viz také

Řízení procesů a prostředí
_open, _wopen