Udostępnij za pośrednictwem


_pipe

Tworzy potok do odczytu i zapisu.

Ważne

Tego interfejsu API nie można używać w aplikacjach wykonywanych w środowisko wykonawcze systemu Windows. Aby uzyskać więcej informacji, zobacz Funkcje CRT nieobsługiwane w aplikacjach platforma uniwersalna systemu Windows.

Składnia

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

Parametry

pfds
Wskaźnik do tablicy dwóch int do przechowywania deskryptorów plików odczytu i zapisu.

psize
Ilość pamięci do zarezerwowania.

textmode
Tryb pliku.

Wartość zwracana

Zwraca wartość 0 w przypadku powodzenia. Zwraca wartość -1, aby wskazać błąd. W przypadku błędu errno ustawiono jedną z następujących wartości:

  • EMFILE, co wskazuje, że nie są dostępne żadne deskryptory plików.

  • ENFILE, który wskazuje przepełnienie tabeli system-file-table.

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

Aby uzyskać więcej informacji na temat tych i innych kodów powrotnych, zobacz errno, _doserrno, _sys_errlisti _sys_nerr.

Uwagi

Funkcja _pipe tworzy potok, który jest sztucznym kanałem we/wy używanym przez program do przekazywania informacji do innych programów. Potok przypomina plik, ponieważ zawiera wskaźnik pliku, deskryptor plików lub oba te elementy. Można go odczytywać lub zapisywać przy użyciu funkcji wejściowych i wyjściowych biblioteki standardowej. Potok nie reprezentuje jednak określonego pliku ani urządzenia. Zamiast tego reprezentuje magazyn tymczasowy w pamięci, który jest niezależny od własnej pamięci programu i jest kontrolowany całkowicie przez system operacyjny.

_pipe_open przypomina, ale otwiera potok do odczytu i zapisu i zwraca dwa deskryptory plików zamiast jednego. Program może używać obu stron rury lub zamknąć ten, którego nie potrzebuje. Na przykład procesor poleceń w systemie Windows tworzy potok podczas wykonywania polecenia takiego jak PROGRAM1 | PROGRAM2.

Standardowy deskryptor danych wyjściowych PROGRAM1 jest dołączony do deskryptora zapisu potoku. Standardowy deskryptor PROGRAM2 wejściowy elementu jest dołączony do deskryptora odczytu potoku. Ten załącznik eliminuje konieczność tworzenia plików tymczasowych w celu przekazania informacji do innych programów.

Funkcja _pipe zwraca dwa deskryptory plików do potoku w argumencie pfds . Element pfds[0] zawiera deskryptor odczytu, a element pfds[1] zawiera deskryptor zapisu. Deskryptory plików potokowych są używane w taki sam sposób jak inne deskryptory plików. (Funkcje wejściowe i wyjściowe _read niskiego poziomu oraz _write mogą odczytywać i zapisywać w potoku). Aby wykryć warunek końca potoku, sprawdź _read żądanie zwracające wartość 0 jako liczbę odczytanych bajtów.

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

W programach wielowątkowych nie jest wykonywane blokowanie. Deskryptory plików, które są zwracane, są nowo otwarte i nie powinny być przywoływane przez żaden wątek do momentu _pipe zakończenia wywołania.

Aby używać _pipe funkcji do komunikowania się między procesem nadrzędnym a procesem podrzędnym, każdy proces musi mieć tylko jeden deskryptor otwarty w potoku. Deskryptory muszą być przeciwieństwami: jeśli element nadrzędny ma otwarty deskryptor odczytu, wówczas element podrzędny musi mieć otwarty deskryptor zapisu. Najłatwiej jest użyć bitowego znaku "lub" (|) na flagi _O_NOINHERIT z textmode. Następnie użyj polecenia _dup lub _dup2 , aby utworzyć dziedziczoną kopię deskryptora potoku, którą chcesz przekazać do elementu podrzędnego. Zamknij oryginalny deskryptor, a następnie zduplikuj proces podrzędny. Po powrocie z wywołania spawn zamknij zduplikowany deskryptor w procesie nadrzędnym. Aby uzyskać więcej informacji, zobacz przykład 2 w dalszej części tego artykułu.

W systemie operacyjnym Windows potok jest niszczony, gdy wszystkie deskryptory zostały zamknięte. (Jeśli wszystkie deskryptory odczytu w potoku zostały zamknięte, zapis w potoku powoduje błąd). Wszystkie operacje odczytu i zapisu w potoku czekają na wystarczającą ilość danych lub wystarczającą ilość miejsca buforu do ukończenia żądania we/wy.

Domyślnie stan globalny tej funkcji jest zakresem aplikacji. Aby zmienić to zachowanie, zobacz Stan globalny w CRT.

Wymagania

Procedura Wymagany nagłówek Opcjonalny nagłówek
_pipe <io.h> <fcntl.h>,1 <errno.h>2

1 Dla _O_BINARY definicji i _O_TEXT .

2 errno definicje.

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

Biblioteki

Wszystkie wersje bibliotek czasu wykonywania języka 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 ) );

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

Przykładowy kod to podstawowa aplikacja filtru. Spowoduje to zduplikowane przez aplikację crt_pipe_beeper po utworzeniu potoku, który kieruje zduplikowaną aplikację stdout do filtru. Filtr usuwa znaki ASCII 7 (sygnał dźwiękowy).

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

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

Zobacz też

Kontrola procesu i środowiska
_open, _wopen