_pipe
Vytvoří kanál pro čtení a zapisování.
Důležité |
---|
Toto API nelze použít v aplikacích, které jsou spuštěny v prostředí Windows Runtime.Další informace naleznete v tématu CRT funkce nejsou podporovány s /ZW. |
int _pipe(
int *pfds,
unsigned int psize,
int textmode
);
Parametry
pfds[2]
Pole pro držení popisovačů souboru čtení a zápisu.psize
Velikost paměti pro rezervaci.textmode
Režim souboru.
Vrácená hodnota
Pokud je úspěšná, vrátí hodnotu 0.Vrátí hodnotu –1, pokud došlo k chybě.Při výskytu chyby errno je nastavena na jednu z těchto hodnot:
EMFILE, což znamená, že nejsou k dispozici žádné další popisovače souboru.
ENFILE, který označuje přetečení tabulky systému souborů.
EINVAL, což znamená, že buď pole pfds je ukazatel s hodnotou null nebo pro textmode byla předána neplatná hodnota.
Další informace o tomto a dalších návratových kódech naleznete v tématu errno, _doserrno, _sys_errlist, and _sys_nerr.
Poznámky
Funkce _pipe vytvoří kanál, což je umělý vstupně-výstupní kanál, který program používá k předání informací do jiných programů.Kanál se podobá souboru, protože má ukazatel souboru, popisovač souboru nebo oba a lze jej číst nebo do něj zapisovat pomocí funkcí vstupu a výstupu standardní knihovny.Kanál však nepředstavuje konkrétní soubor nebo 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 výhradně operačním systémem.
_pipe se podobá _open, ale otevře kanál pro čtení a zápis a vrátí dva popisovače souboru místo jednoho.Program můžete používat obě strany kanálu nebo zavřít ten, který nepotřebuje.Například procesor příkazu v systému Windows vytváří kanál, když je spuštěn příkaz jako PROGRAM1 | PROGRAM2.
Standardní výstupní popisovač PROGRAM1 se připojuje k popisovači zápisu kanálu.Standardní vstupní popisovač PROGRAM2 se připojuje k popisovači čtení kanálu.To eliminuje potřebu vytvářet dočasné soubory pro předávání informací do jiných programů.
Funkce _pipe vrátí dva popisovače souborů do kanálu v argumentu pfds.Prvek pfds[0] obsahuje popisovače čtení a prvek pfds[1] obsahuje popisovač zápisu.Popisovače souborů kanálu se používají stejným způsobem jako ostatní popisovače souborů. (Funkce nižší vstupní a výstupní úrovně _read a _write mohou číst z a zapisovat do kanálu.) Ke zjištění stavu konce trubky se podívejte na požadavek _read, který vrací hodnotu 0 jako počet přečtených bajtů.
Argument psize určuje velikost paměti v bajtech, která se má vyhradit pro kanál.Argument textmode určuje režim překladu pro kanál.Konstanta manifestu _O_TEXT určuje překlad textu a konstanta _O_BINARY určuje binární překlad. (Viz fopen, _wfopen pro popis textu a binárních režimů.) Pokud argumentu textmode je 0, _pipe používá výchozí režim překladu určený proměnnou výchozího režimu _fmode.
Žádné uzamčení se neprovádí v programech s více vlákny.Popisovače souborů, které jsou vráceny, jsou nově otevřeny a neměly by být odkazovány z žádného vlákna do dokončení volání _pipe.
Chcete-li použít funkci _pipe ke komunikaci 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 opaky: pokud má nadřazený prvek otevřený popisovač pro čtení, pak musí mít podřízený prvek otevřený popisovač zápisu.Nejjednodušší způsob, jak to provést, je provést operaci OR (|) příznak _O_NOINHERIT s textmode.Pak pomocí _dup nebo _dup2 vytvořte dědičnou kopii popisovače kanálu, který chcete podřízené položce předat.Zavřete původní popisovač a pak spusťte podřízený proces.Při návratu z volání vzniku zavřete duplicitní popisovač v nadřazeném procesu.Další informace naleznete v příkladu 2 dále v tomto článku.
V operačním systému Windows je kanál zničen, pokud jsou všechny jeho popisovače uzavřeny. (Pokud byly všechny popisovače čtení na kanálu zavřeny, pak zápis do kanálu způsobí chybu.) Všechny operace čtení a zápisu na kanálu čekají, dokud není k dispozici dostatek dat nebo dostatek vyrovnávací paměti k dokončení vstupně-výstupního požadavku.
Požadavky
Rutina |
Požadované záhlaví |
Volitelné záhlaví |
---|---|---|
_pipe |
<io.h> |
<fcntl.h>, 1 <errno.h>2 |
1 Pro _O_BINARY a definice _O_TEXT.
2 errno definice.
Další informace o kompatibilitě naleznete v tématu Kompatibilita.
Knihovny
Všechny verze běhových knihoven 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 ) );
}
}
}
Výstup ukázky
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
Toto je základní aplikace filtru.Dává vzniknout aplikaci crt_pipe_beeper po vytvoření kanálu, který přesměruje stdout vytvořené aplikace do filtru.Filtr odstraní znaky ASCII 7 (zvukový signál).
// 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;
}
Aktuální 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;
}
Výsledek
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...
Ekvivalent v rozhraní .NET Framework
Nelze použít. Pokud chcete volat standardní funkci jazyka C, použijte PInvoke. Další informace naleznete v tématu Příklady vyvolání platformy.