_pipe
Okuma ve yazma için bir boru oluşturur.
Önemli
Bu API, Windows Çalışma Zamanı yürütülen uygulamalarda kullanılamaz. Daha fazla bilgi için bkz. Evrensel Windows Platformu uygulamalarında desteklenmeyen CRT işlevleri.
Sözdizimi
int _pipe(
int *pfds,
unsigned int psize,
int textmode
);
Parametreler
pfds
Okuma ve yazma dosya tanımlayıcılarını tutmak için ikilik int
bir dizi işaretçisi.
psize
Ayrılan bellek miktarı.
textmode
Dosya modu.
Dönüş değeri
Başarılı olursa 0 döndürür. Hata belirtmek için -1 döndürür. Hatada, errno
şu değerlerden birine ayarlanır:
EMFILE
, başka dosya tanımlayıcılarının kullanılamadığını gösterir.ENFILE
, sistem-dosya-tablo taşma durumunu gösterir.EINVAL
, dizininpfds
null bir işaretçi olduğunu veya içintextmode
geçersiz bir değerin geçirildiğini gösterir.
Bunlar ve diğer iade kodları hakkında daha fazla bilgi için bkz. errno
, _doserrno
, _sys_errlist
ve _sys_nerr
.
Açıklamalar
_pipe
işlevi, bir programın diğer programlara bilgi geçirmek için kullandığı yapay bir G/Ç kanalı olan bir kanal oluşturur. Kanal, dosya işaretçisi, dosya tanımlayıcısı veya her ikisi de olduğundan dosyaya benzer. Ayrıca, Standart Kitaplık giriş ve çıkış işlevleri kullanılarak buradan okunabilir veya yazılabilir. Ancak, kanal belirli bir dosyayı veya cihazı temsil etmez. Bunun yerine, programın kendi belleğinden bağımsız olan ve tamamen işletim sistemi tarafından denetlenen bellekteki geçici depolamayı temsil eder.
_pipe
_open
benzer ancak okuma ve yazma için kanalı açar ve bir yerine iki dosya tanımlayıcısı döndürür. Program borunun her iki tarafını da kullanabilir veya ihtiyacı olmayanı kapatabilir. Örneğin, Windows'taki komut işlemcisi gibi PROGRAM1 | PROGRAM2
bir komut yürütürken bir kanal oluşturur.
standart çıkış tanımlayıcısı PROGRAM1
, kanalın yazma tanımlayıcısına eklenir. standart giriş tanımlayıcısı PROGRAM2
, borunun okuma tanımlayıcısına eklenir. Bu ek, diğer programlara bilgi geçirmek için geçici dosyalar oluşturma gereksinimini ortadan kaldırır.
İşlev, _pipe
bağımsız değişkendeki kanala iki dosya tanımlayıcısı pfds
döndürür. [0] öğesi pfds
okuma tanımlayıcısını, [1] öğesi pfds
de yazma tanımlayıcısını içerir. Kanal dosyası tanımlayıcıları, diğer dosya tanımlayıcıları ile aynı şekilde kullanılır. (Alt düzey giriş ve çıkış işlevleridir _read
ve _write
bir kanaldan okuyabilir ve bir kanala yazabilir.) Kanal sonu koşulunu algılamak için okunan bayt sayısı olarak 0 döndüren bir _read
istek olup olmadığını denetleyin.
psize
bağımsız değişkeni, kanal için ayrılan bellek miktarını bayt cinsinden belirtir. textmode
bağımsız değişkeni kanal için çeviri modunu belirtir. Bildirim sabiti _O_TEXT
ansi metin çevirisi belirtir ve sabit _O_BINARY
ikili çeviri belirtir. (Metin ve ikili modların açıklaması için bkz fopen
. . _wfopen
textmode
Bağımsız değişken 0 ise, _pipe
varsayılan mod değişkeni _fmode
tarafından belirtilen varsayılan çeviri modunu kullanır.
Çok iş parçacıklı programlarda kilitleme gerçekleştirilmez. Döndürülen dosya tanımlayıcıları yeni açılır ve çağrı tamamlanana _pipe
kadar herhangi bir iş parçacığı tarafından başvurulmamalıdır.
üst işlem ile alt işlem arasında iletişim kurmak üzere işlevini kullanmak _pipe
için, her işlemin kanalda yalnızca bir açık tanımlayıcısı olmalıdır. Tanımlayıcıların karşıt olması gerekir: Üst öğede açık bir okuma tanımlayıcısı varsa, alt öğede açık bir yazma tanımlayıcısı olmalıdır. ile bayrağında bit düzeyinde "veya" (|
) kullanmak en kolayıdır _O_NOINHERIT
textmode
. Ardından, alt öğeye geçirmek istediğiniz kanal tanımlayıcısının devralınabilir bir kopyasını oluşturmak için veya _dup2
kullanın_dup
. Özgün tanımlayıcıyı kapatın ve ardından alt işlemi oluşturun. Oluşturma çağrısından geri döndüğünüzde, üst işlemdeki yinelenen tanımlayıcıyı kapatın. Daha fazla bilgi için bu makalenin sonraki 2. örneğine bakın.
Windows işletim sisteminde, tüm tanımlayıcıları kapatıldığında bir boru yok edilir. (Borudaki tüm okuma tanımlayıcıları kapatılmışsa, kanala yazmak bir hataya neden olur.) Kanaldaki tüm okuma ve yazma işlemleri, G/Ç isteğini tamamlamak için yeterli veri veya yeterli arabellek alanı olana kadar bekler.
Varsayılan olarak, bu işlevin genel durumunun kapsamı uygulama olarak belirlenmiştir. Bu davranışı değiştirmek için bkz. CRT'de Genel durum.
Gereksinimler
Yordam | Gerekli başlık | İsteğe bağlı üst bilgi |
---|---|---|
_pipe |
<io.h> |
<fcntl.h> ,1 <errno.h> 2 |
1 ve tanımları için _O_BINARY
_O_TEXT
.
2 errno
tanım.
Daha fazla uyumluluk bilgisi için bkz . Uyumluluk.
Kitaplıklar
C çalışma zamanı kitaplıklarının tüm sürümleri.
Örnek 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.
Örnek 2
Örnek kod, temel bir filtre uygulamasıdır. Oluşturulan uygulamanın crt_pipe_beeper
filtreye yönlendiren bir boru oluşturduğunda uygulamayı stdout
oluşturur. Filtre ASCII 7 (bip) karakterlerini kaldırır.
// 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;
}
Gerçek filtre uygulaması:
// 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...