Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
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 polepfdsje 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_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.
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...