_pipe
Stellt eine Pipe zum Lesen und Schreiben erstellt.
Wichtig |
---|
Diese API kann nicht in den Anwendungen verwendet werden, die in Windows-Runtime ausführen.Weitere Informationen finden Sie unter CRT-Funktionen unterstützt nicht mit /ZW. |
int _pipe( int *pfds, unsigned int psize, int textmode );
Parameter
pfds[2]
Array, um die Favoritenauswahl angehalten und von Dateideskriptoren zu schreiben.psize
Speicher für die Reservierung.textmode
Dateimodus.
Rückgabewert
Gibt 0 zurück, wenn erfolgreich.EINGABETASTE - 1, um eines Fehlers anzugeben.Bei einem Fehler wird errno an einen dieser Werte festgelegt:
EMFILE, das angibt, dass nicht mehr Dateideskriptoren verfügbar sind.
ENFILE, das einen System-DateiTabellenüberlauf angibt.
EINVAL, das angibt, dass entweder das Array pfds ein NULL-Zeiger ist, oder dass ein ungültiger Wert für textmode übergeben wurde.
Weitere Informationen zu diesen und anderen Rückgabecodes, finden Sie unter errno, _doserrno, _sys_errlist und _sys_nerr.
Hinweise
Die _pipe-Funktion stellt eine Pipe erstellt, die ein künstlicher Ein-/Ausgabekanal ist, dem ein Programm verwendet, um Informationen zu anderen Programmen zu übergeben.Eine Pipe ähnelt einer Datei, da sie einen Dateizeiger, einen Dateideskriptor oder beide verfügt, und sie kann von gelesen oder zu, indem die Standardbibliothekseingabe und -Ausgabefunktionen geschrieben werden.Bei einer Pipe keine bestimmte Datei oder ein Gerät dar.Stattdessen stellt sie temporäre Speicherung im Arbeitsspeicher dar, der von eigenen Arbeitsspeicher des Programms ist und vollständig vom Betriebssystem gesteuert wird.
_pipe ähnelt, jedoch _open öffnet die - Pipe zum Lesen und Schreiben und gibt zwei Dateideskriptoren anstelle eines zurück.Das Programm kann beide Seiten der Pipe verwenden oder das schließen, das sie nicht benötigt.Zum Beispiel stellt der Befehlsprozessor in Windows eine Pipe erstellt, wenn er einen Befehl wie PROGRAM1 | PROGRAM2 ausführt.
Der Standardausgabedeskriptor von PROGRAM1 wird der Pipe schreiben Deskriptor angefügt.Der Standardeingabedeskriptor von PROGRAM2 wird dem Deskriptor der Pipe Leseangefügt.Dadurch entfällt die Notwendigkeit, temporäre Dateien zu erstellen, um Informationen zu anderen Programmen zu übergeben.
Die _pipe-Funktion gibt zwei Dateideskriptoren zur Pipe im pfds-Argument zurück.Das - Element pfds[0] enthält den Lesedeskriptor und das Element pfds[1] enthält den schreibensdeskriptor.Pipedateideskriptoren werden auf die gleiche Weise wie andere Dateideskriptoren verwendet.(Die Eingabe und die Ausgabefunktionen auf niedriger Ebene _read und _write können von lesen und eine Pipe schreiben.) Um die Zustand zu erkennen am Ende des Prozesses, suchen Sie nach einer _read Anforderung 0 als die Anzahl der gelesenen Bytes zurückgibt.
Das psize-Argument gibt den Arbeitsspeicher, in Bytes, für die Reservierung für die Pipe an.Das textmode-Argument gibt den Übersetzungsmodus für die Pipe an.Manifeste konstante _O_TEXT gibt eine Textübersetzung an, und konstante _O_BINARY gibt binäre Übersetzung an.(Siehe fopen, _wfopen für eine Beschreibung von Text- und Binärdateimodi.) Wenn das Argument 0 ist, textmode verwendet _pipe den standardmäßigen Übersetzungsmodus, der von der StandardModusvariable _fmode angegeben wird.
In Multithreadprogrammen wird keine Sperre ausgeführt.Die Dateideskriptoren, die zurückgegeben werden, sind neu geöffnet und sollten nicht von einem Thread verwiesen werden, bis _pipe nach der Aufruf abgeschlossen ist.
Um die _pipe-Funktion mit zwischen einem übergeordneten Prozess und einen untergeordneten Prozess zu kommunizieren, muss jeder Prozess nur einen Deskriptor haben, der auf der Pipe geöffnet ist.Die Deskriptoren müssen Gegenteile sein: Wenn das übergeordnete Element einen geöffneten Lesedeskriptor verfügt, muss das untergeordnete Element einen geöffneten schreibensdeskriptor haben.Die einfachste Möglichkeit, hierzu ist zu OR (|_O_NOINHERIT ) das - Flag mit textmode.Verwenden Sie anschließend _dup oder _dup2, eine vererbbare Kopie des Pipedeskriptors zu erstellen, den Sie dem untergeordneten Element speichern möchten.Schließen Sie den ursprünglichen Deskriptor, und erstellen Sie dann den untergeordneten Prozess.Bei Rückgabe aus dem Fischeieraufruf, schließen Sie den doppelten Deskriptor im übergeordneten Prozess.Weitere Informationen finden Sie unter Beispiel 2 weiter unten in diesem Artikel.
Im Windows-Betriebssystem wird eine Pipe zerstört, wenn alle zugehörigen Deskriptoren geschlossen wurden.(Wenn alle Lesedeskriptoren auf der Pipe geschlossen wurden, dann verursacht Schreiben auf die Pipe einen Fehler.) Alle Lese- und Schreibvorgänge auf der Pipe warten, bis sie genügend Daten oder ausreichend Pufferplatz gibt, um die E/A-Anforderung abzuschließen.
Anforderungen
Routine |
Erforderlicher Header |
Optionaler Header |
---|---|---|
_pipe |
<io.h> |
<fcntl.h>, 1 <errno.h>2 |
1 Für _O_BINARY und _O_TEXT Definitionen.
2 errno Definitionen.
Weitere Kompatibilitätsinformation finden Sie unter Kompatibilität.
Bibliotheken
Alle Versionen C-Laufzeitbibliotheken.
Beispiel 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 ) );
}
}
}
Beispielausgabe
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.
Beispiel 2
Dies ist eine grundlegende Filter-Anwendung.Es erzeugt die Anwendung crt_pipe_beeper, nachdem eine Pipe, die das generierte stdout der Anwendung auf den Filter verweist.Der Filter entfernt Zeichen 7 (ASCII Signalton).
// 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;
}
Die tatsächliche Filter-Anwendung:
// 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;
}
Ausgabe
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...
.NET Framework-Entsprechung
Nicht zutreffend. Um die Standard-C-Funktion aufzurufen, verwenden Sie PInvoke. Weitere Informationen finden Sie unter Beispiele für Plattformaufrufe.