_pipe

Tworzy potok do odczytu i zapisu.

Ważna uwagaWażne

Ten interfejs API nie może być stosowany w aplikacjach, które są wykonywane w Środowisko wykonawcze systemu Windows .Aby uzyskać więcej informacji, zobacz Funkcje CRT nieobsługiwane przez /ZW.

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

Parametry

  • pfds[2]
    Tablica do przechowywania deskryptorów plików odczytu i zapisu.

  • psize
    Ilość pamięci, którą należy zarezerwować.

  • textmode
    Tryb pliku.

Wartość zwracana

Zwraca wartość 0, jeśli kończy się pomyślnie.Zwraca wartość -1, aby wskazać błąd.W przypadku błędu errno jest ustawiony na jedną z następujących wartości:

  • EMFILE, która wskazuje, że nie ma więcej dostępnych deskryptorów plików.

  • ENFILE, która wskazuje przepełnienie tabeli plików systemu.

  • EINVAL, który wskazuje, że tablica pfds jest wskaźnikiem typu null lub przekazaną nieprawidłową wartością dla textmode.

Aby uzyskać informacje o tych i innych kodach powrotnych, zobacz errno, _doserrno, _sys_errlist, and _sys_nerr.

Uwagi

_pipe funkcja tworzy rury, który jest sztucznym kanałem We/Wy, którego program używa do przekazania informacji do innych programów.Potok przypomina plik, ponieważ ma wskaźnik pliku, deskryptor pliku lub oba, i może być odczytywany lub zapisywany za pomocą funkcji standardowej biblioteki danych wejściowych i wyjściowych.Jednakże potok nie reprezentuje określonego pliku lub urządzenia.Zamiast tego, reprezentuje tymczasowy magazyn w pamięci, która jest niezależna od pamięci tego programu i jest całkowicie kontrolowana przez system operacyjny.

_pipe przypomina _open, ale otwiera potok do czytania i pisania i zwraca dwa deskryptory pliku zamiast jednego.Program może użyć obu stron potoku lub zamknąć tę, której nie potrzebuje.Na przykład, procesor poleceń w systemie Windows tworzy potok, kiedy wykonuje polecenia takie jak PROGRAM1 | PROGRAM2.

Standardowe wyjście deskryptora PROGRAM1 jest dołączone do deskryptora wpisu potoku.Standardowe wejściowy deskryptora PROGRAM2 jest dołączone do deskryptora odczytu potoku.Eliminuje to potrzebę tworzenia tymczasowych plików do przekazania informacji do innych programów.

_pipe , funkcja zwraca dwa deskryptory plików do potoku pfds argumentu.Element pfds[0] zawiera deskryptor odczytu, a element pfds[1] zawiera deskryptor zapisu.Deskryptory rury są używane w taki sam sposób jak inne deskryptory plików. (Funkcje danych wejściowych i wyjściowych niskiego poziomu _read i _write mogą odczytywać z i zapisywać do potoku). Aby wykryć warunek-potok, sprawdź _read żądanie, który zwraca wartość 0 jako liczbę odczytanych bajtów.

psize argument określa ilość pamięci w bajtach, do zarezerwowania dla potoku.textmode argument określa tryb translacji dla potoku.Stała manifestu _O_TEXT określa tłumaczenie tekstu i stałą _O_BINARY określa tłumaczenie binarne. (Zobacz fopen, _wfopen, aby uzyskać informacje na temat opisu trybów tekstowych i binarnych). Jeśli argument textmode ma wartość 0, _pipe używa domyślnie trybu konwersji określonego przez zmienną trybu domyślnego _fmode.

W przypadku programów wielowątkowych, blokowanie nie jest wykonywane.Deskryptory plików, które są zwracane są otwarte i nie powinno być do nich odwołań w żadnym z wątków, aż po _pipe zakończeniu wywołanie.

Aby użyć _pipe funkcji do komunikowania się między procesem nadrzędnym a proces podrzędny, każdy proces musi mieć tylko jeden deskryptor otwarty na rurze.Deskryptory muszą być przeciwieństwem: jeśli element nadrzędny ma deskryptor odczytu Otwórz, następnie element podrzędny musi mieć deskryptor zapisu, Otwórz.Najprostszym sposobem na to jest OR ()|) znacznik _O_NOINHERIT z textmode.Następnie należy użyć _dup lub _dup2 aby utworzyć dziedziczne kopię deskryptora potoku, który chcesz przekazać do elementu podrzędnego.Zamknij oryginalny deskryptor, a następnie powiększ liczbę procesów potomnych.Po powrocie z wielokrotnego wywołania, zamknij deskryptora duplikatów w procesie nadrzędnym.Aby uzyskać więcej informacji, zobacz przykład 2 w dalszej części tego paragrafu.

W systemie operacyjnym Windows potok jest niszczony, kiedy wszystkie jego deskryptory zostają zamknięte. (Jeśli wszystkie deskryptory odczytu do potoku zostały zamknięte, wówczas zapis do potoku powoduje błąd). Wszystkie operacje odczytu i zapisu na potoku oczekują, aż będzie wystarczająca ilość danych lub wystarczająca przestrzeń w buforze do wykonania żądania We/Wy.

Wymagania

Procedura

Wymagany nagłówek

Opcjonalny nagłówek

_pipe

<io.h>

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

1 Dla definicji _O_BINARY i _O_TEXT.

2 errno definicje.

Aby uzyskać więcej informacji na temat zgodności, zobacz Zgodność.

Biblioteki

Wszystkie wersje Bibliotek uruchomieniowych C.

Przykład 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 ) );

      }
   }
}

Przykładowe dane wyjściowe

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.

Przykład 2

Jest to aplikacja podstawowa filtru.Tworzy z niczego aplikację crt_pipe_beeper po utworzeniu przewodu kierującego wskaźnik stdout utworzonej z niczego aplikacji do filtra.Ten filtr usuwa znaki 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;
}

rzeczywiste zastosowanie 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;
}

Dane wyjściowe

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

Odpowiednik w programie .NET Framework

Nie dotyczy. Aby wywołać standardową funkcję C, należy użyć PInvoke. Aby uzyskać więcej informacji, zobacz Przykłady wywołań platformy.

Zobacz też

Informacje

Procedury kontroli środowiska

_open, _wopen