_pipe
Tworzy potok do odczytu i zapisu.
![]() |
---|
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.