_pipe
Okuma ve yazma için bir kanal oluşturur.
Önemli |
---|
Bu API Windows Çalışma Zamanı, içinde yürütülen uygulamalarda kullanılmaz.Daha fazla bilgi için bkz /ZW ile desteklenmeyen CRT işlevleri. |
int _pipe(
int *pfds,
unsigned int psize,
int textmode
);
Parametreler
pfds[2]
Okuma ve yazma dosya tanımlayıcılarını tutma dizisi.psize
Ayrılacak bellek miktarı.textmode
Dosya modu.
Dönüş Değeri
Başarılı olursa 0 döndürür.Bir hatayı göstermek için –1 döndürür.Hata durumunda, errno şu değerlerden birine ayarlanır:
EMFILE, başka kullanılabilir dosya tanımlayıcısı bulunmadığını gösterir.
Sistem dosyası tablo taşmasını gösteren ENFILE.
pfds dizisinin boş bir işaretçi olduğunu veya textmode için geçersiz bir değer geçirildiğini belirten EINVAL.
Bunlar ve diğer döndürme kodları hakkında daha fazla bilgi için bkz. errno, _doserrno, _sys_errlist, and _sys_nerr.
Notlar
_pipe işlevi, bir programın başka programlara bilgi geçmek için kullandığı yapay bir G/Ç yolu olan yeni bir kanal oluşturur.Dosya işaretçisi, dosya tanımlayıcısı veya her ikisi de bulunduğundan, kanal dosyaya benzer ve Standart Kitaplık girişi ve çıkışı kullanılarak kanala yazılabilir veya kanaldan okunabilir.Ancak, bir kanal belirli bir dosyayı veya cihazı temsil etmez.Bunun yerine, programın kendi bellek bağımsız ve tamamen işletim sistemi tarafından denetlenen bellekteki geçici depolamayı temsil eder.
_pipe_open öğesine benzer ancak kanalı okuma ve yazma için açar, bir yerine iki dosya tanımlayıcı döndürür.Program kanalın her iki tarafını kullanabilir veya ihtiyaç duymadığı tarafı kapatabilir.Örneğin, Windows'taki komut işleyicisi, PROGRAM1 | PROGRAM2 gibi bir komut yürüttüğünde bir kanal oluşturur.
PROGRAM1 standart çıkış tanımlayıcısı, kanalın yazma tanımlayıcısına iliştirilmiş.PROGRAM2 standart giriş tanımlayıcısı, kanalın okuma tanımlayıcısına iliştirilmiş.Bu, diğer programlara bilgi geçirmek için geçici dosyalar oluşturma gereksinimini ortadan kaldırır.
_pipe işlevi pfds bağımsız değişkenindeki kanala iki dosya tanımlayıcısı döndürür.pfds[0] öğesi okuma tanımlayıcısını, pfds[1] öğesi ise yazma tanımlayıcısını içerir.Kanal dosya tanımlayıcıları, diğer dosya tanımlayıcılarıyla aynı şekilde kullanılır. (Alt düzey giriş ve çıkış işlevleri _read ve _write bir kanaldan okunabilir ve bir kanala yazılabilir.) Kanal bitiş koşulunu algılamak için, okunan bayt sayısı olarak 0 getiren bir _read isteği kontrolü yapın.
psize bağımsız değişkeni kanala ayrılacak bayt cinsinden bellek miktarını belirler.textmode bağımsız değişkeni, kanal için çeviri modunu belirtir.Bildirim sabiti _O_TEXT bir metin dönüşümü belirler ve, _O_BINARY sabiti ikili dönüşümü belirler. (Metnin ve ikili modların tanımı için bkz: fopen, _wfopen ) textmode bağımsız değişkeni 0'sa, _pipe, varsayılan modlu _fmode değişkeninin belirttiği varsayılan çeviri modunu kullanır.
Çoklu iş parçacıklı programlarda hiçbir kilitleme gerçekleştirilmez.Geri dönen Dosya tanımlayıcıları yeni açılmıştır ve _pipe çağrısı tamamlanmadan herhangi bir iş parçacığı başvurmamalıdır.
Bir ana işlem ve alt işlem arasında iletişim kurmak üzere _pipe işlevini kullanmak için, her bir işlemin kanalda açık yalnızca bir tanımlayıcısı olmalıdır.Tanımlayıcıların birbirinin zıttı olması gerekir: üst öğenin açık bir okuma tanımlayıcısı varsa, alt öğenin açık bir yazma tanımlayıcısı olması gerekir.Bunu yapmanın en kolay yolu OR kullanmaktır (|) textmode ile _O_NOINHERIT bayrağı.Daha sonra, _dup veya _dup2 kullanarak, alta geçirmek istediğiniz kanal tanımlayıcısının devralınabilir bir kopyasını oluşturun.Özgün tanımlayıcıyı kapatın ve sonra alt işlemi oluşturun.Oluşturma çağrısından dönüşte, üst işlemdeki yinelenen tanımlayıcıyı kapatın.Daha fazla bilgi için bu makalede daha sonra gelen Örnek 2'ye bakın.
Windows işletim sisteminde, kendi tanımlayıcılarının tümü kapandığında kanal yokolur. (Kanal üzerindeki tüm okuma tanımlayıcıları kapatılmışsa, kanala yazmak hataya sebep olur.) I/O isteğini tamamlamak için yeterli veri veya arabellek alanı oluncaya kadar kanal üzerindeki tüm okuma ve yazma işlemleri bekler.
Gereksinimler
Yordam |
Gerekli başlık |
İsteğe bağlı üst bilgi |
---|---|---|
_pipe |
<io.h> |
<fcntl.h>,1 <errno.h>2 |
1 _O_BINARY ve _O_TEXT tanımlarına ilişkin.
2 errno tanımlar.
Uyumluluk hakkında daha fazla bilgi için bkz. Uyumluluk.
Kitaplıklar
C çalışma zamanı kitaplıklarının çoklu iş parçacığı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 ) );
}
}
}
Örnek Çıktı
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
Bu, temel bir filtre uygulamasıdır.Oluşturulan uygulamanın stdout'unu filtreye yönlendiren bir kanal oluşturduktan sonra crt_pipe_beeper uygulamasını 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;
}
Çıktı
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 Eşdeğeri
Uygulanamaz. Standart C işlevini çağırmak için PInvoke kullanın. Daha fazla bilgi için bkz. Platform Çağırma Örnekleri.