_pipe
Tworzy potok do odczytu i zapisu.
Ważne |
---|
Ten interfejs API nie można używać w aplikacji, których wykonywanie w Środowisko wykonawcze systemu Windows.Aby uzyskać więcej informacji, zobacz CRT funkcje nie obsługiwane przez /ZW. |
int _pipe( int *pfds, unsigned int psize, int textmode );
Parametry
pfds[2]
Tablica do przechowywania odczytu i zapisu deskryptorów plików.psize
Ilość pamięci, aby zarezerwować.textmode
Tryb pliku.
Wartość zwracana
Zwraca wartość 0, jeśli kończy się pomyślnie.Zwraca-1, aby wskazać błąd.W przypadku błędu errno jest ustawiona na jeden z następujących wartości:
EMFILE, która oznacza, że nie więcej deskryptorów plików są dostępne.
ENFILE, która wskazuje przepełnienie tabeli system plików.
EINVAL, który wskazuje, że albo tablica pfds jest pusty wskaźnik lub nieprawidłową wartość dla textmode przekazano.
Aby uzyskać więcej informacji na temat tych i innych kody powrotne, zobacz errno, _doserrno, _sys_errlist i _sys_nerr.
Uwagi
_pipe Funkcja tworzy rury, który jest sztuczny kanał We/Wy, który program używa do przekazania informacji do innych programów.Potok podobny do pliku, ponieważ ma on pliku (EOF) lub deskryptor pliku i może być odczytywane lub zapisywane przy użyciu biblioteki standardowej wejście i wyjście z funkcji.Jednakże potoku nie reprezentuje określonego pliku lub urządzenia.Zamiast tego reprezentuje tymczasowego przechowywania w pamięci, która jest niezależna od pamięci tego programu i jest całkowicie kontrolowane przez system operacyjny.
_pipepodobny do _open , ale otwiera potoku do odczytu i zapisu i zwraca dwa foldery deskryptory zamiast jednego.Program można użyć obu stron, potoku lub zamknąć ten, który nie ma potrzeby.Na przykład procesor poleceń w systemie Windows tworzy potok, kiedy wykonuje polecenia takie jak PROGRAM1 | PROGRAM2.
Standard wyjście deskryptor PROGRAM1 jest dołączony do deskryptora zapisu w potoku.Standardowe deskryptora wejściowego z PROGRAM2 jest dołączony do deskryptora odczytu z potoku.Eliminuje to potrzebę tworzenia tymczasowych plików do przekazania informacji do innych programów.
_pipe , Funkcja zwraca dwa deskryptorów plików na rurze w pfds argument.Element pfds[0] zawiera deskryptor odczytu i element pfds[1] zawiera deskryptor zapisu.Deskryptory potoku są używane w taki sam sposób jak inne deskryptorów plików.(Niskiego poziomu wejście i wyjście funkcji _read i _write można odczytać i zapisać do potoku.) Do wykrywania warunku zakończenia rur, sprawdzaj _read żądanie, które zwraca wartość 0 jako liczba bajtów odczytanych.
psize Argument określa ilość pamięci w bajtach, aby zarezerwować 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 binarne translacji.(Zobacz fopen, _wfopen opis trybów tekstowych i binarnych.) Jeśli textmode argument ma wartość 0, _pipe używa domyślnie tryb konwersji określoną przez zmienną domyślny tryb _fmode.
W programów wielowątkowych blokowania nie jest wykonywane.Deskryptorów plików, które są zwracane są otwarty i nie powinny się odwoływać przez dowolny wątek, aż po _pipe zakończeniu rozmowy.
Aby użyć _pipe funkcja do komunikacji między procesu nadrzędnego i proces potomny, każdy proces musi mieć tylko jeden deskryptor otwarte na potoku.Deskryptory musi być przeciwieństwa: Jeśli obiekt nadrzędny ma odczytu deskryptora otworzyć, a następnie dziecko musi mieć deskryptor zapisu, Otwórz.Najprostszym sposobem wykonania tego zadania jest OR ()|) the _O_NOINHERIT flag with textmode.Następnie należy użyć _dup lub _dup2 do utworzenia dziedziczne kopię deskryptora potoku, który ma być przekazywany do podrzędnego.Zamknij deskryptora oryginalnego, a następnie uruchomienie procesu potomnego.Po powrocie z wywołania spawn, zamknij deskryptora zduplikowane 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, kiedy wszystkie deskryptory jej zamknięciu.(Jeśli zostały zamknięte wszystkie deskryptory odczytu na rurze, następnie zapisu do potoku powoduje błąd). Wszystkie operacje odczytu i zapisu w potoku podczas oczekiwania do czasu wystarczającej ilości danych lub za mało miejsca w buforze do realizacji żądania We/Wy.
Wymagania
Rozpoczęto wykonywanie procedury |
Wymaganego nagłówka |
Opcjonalny nagłówka |
---|---|---|
_pipe |
<io.h> |
<fcntl.h>, 1 <errno.h> 2 |
1 Na _O_BINARY i _O_TEXT definicje.
2 errno definicje.
Informacji dotyczących zgodności, zobacz Zgodność.
Biblioteki
Wszystkie wersje programu biblioteki uruchomieniowej 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 podstawowe filtru.Po utworzeniu potoku, kierujący stdout zduplikowanego aplikacji do filtru uruchamiany jest proces crt_pipe_beeper aplikacji.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;
}
Aplikacja rzeczywistą filtra:
// 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ływać funkcji C standardowej, należy użyć PInvoke. Aby uzyskać więcej informacji, zobacz Platforma wywołać przykłady.