_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 polepfds
je ukazatel null nebo že byla předána neplatná hodnota protextmode
.
Další informace o těchto a dalších návratových kódech naleznete v tématu , , , a_sys_nerr
. _sys_errlist
_doserrno
errno
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 _fmode
vý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.
2 errno
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...