_pipe
建立讀取和寫入的一個管道。
重要事項 |
---|
這個應用程式開發介面無法用來在 Windows 執行階段中執行的應用程式。如需詳細資訊,請參閱 CRT 函式不支援使用 /ZW。 |
int _pipe( int *pfds, unsigned int psize, int textmode );
參數
pfds[2]
保留陣列的讀取和寫入檔案描述項。psize
記憶體量會保留。textmode
檔案模式。
傳回值
傳回 0,如果成功。傳回–指示錯誤的 1。在錯誤, errno 會設為下列其中一個值:
EMFILE,表示沒有其他檔案描述項沒有可用的。
ENFILE,表示系統檔案表溢位。
EINVAL,表示 pfds 陣列為 null 指標或 textmode 指定了無效的值傳遞。
如需這些與任何其他傳回碼的詳細資訊,請參閱 errno、 _doserrno、 _sys_errlist 和 _sys_nerr。
備註
_pipe 函式會建立 管道,是一條人工 I/O 通道程式使用傳遞資訊至其他程式。管道類似檔案,因為它的檔案指標,的檔案描述項或兩者,使用標準程式庫輸入和輸出函式,,且可以讀取或寫入。不過,管道不代表特定檔案或裝置。相反地,它表示是程式的記憶體獨立和完全是由作業系統控制的記憶體的暫時儲存區。
_pipe 類別與 _open 類似,但是開啟來讀取和寫入管道並傳回兩個檔案描述項而不是一個。程式可以使用管道的兩方或結束它不需要的值。例如,在中,當它執行命令 (例如 PROGRAM1 | PROGRAM2) 時,視窗的命令處理器建立管道。
PROGRAM1 標準輸出描述項附加至管道的寫入描述項。PROGRAM2 標準輸入描述項附加至管道讀取描述項。這樣便不需要建立暫存檔案給其他程式傳遞資訊。
_pipe 函式會傳回兩個檔案描述於 pfds 引數的管道。這個項目 pfds[0] 包含讀取描述項和項目 pfds[1] 包含寫入描述項。管道檔以及與其他檔案描述項來使用。(低階輸入和輸出函式 _read 和 _write 可以讀取和寫入管道)。若要偵測關閉管道情況,請檢查傳回 0 的 _read 要求,位元組數讀取。
psize 引數會指定位元組記憶體量,,為管道保留。textmode 引數為管道指定版本模式。資訊清單常數 _O_TEXT 指定文字轉譯,因此,常數 _O_BINARY 指定二進位轉譯。(指定文字和二進位模式的說明請參閱 fopen _wfopen )。如果 textmode 引數為 0 時, _pipe 所使用的預設方式變數 _fmode指定版本模式的預設值。
在多執行緒的程式,鎖定尚未實作。傳回的檔案描述項是新開啟的,不能由任何執行緒參考,在 _pipe 呼叫完成之後。
若要使用 _pipe 函式通訊父處理序與子處理序之間,每個處理序只能有一個描述項開啟管道。描述元必須是內部:如果父代已開啟讀取描述項,則子系必須開啟寫入描述項。最簡單的方式是對 OR (|) 具有 textmode的 _O_NOINHERIT 旗標。然後,使用 _dup 或 _dup2 建立您想要傳遞給子系管道描述項可繼承的複本。關閉原始的描述元,然後產生子處理序。在從傳回繁衍呼叫,關閉在父處理序的複本描述元。如需詳細資訊,請參閱範例 2 以後本文。
在 Windows 作業系統,管道,當它所有的描述項關閉時,會終結。(如果所有讀取管道的描述元關閉,然後寫入管道產生錯誤)。所有在等待管道讀取和寫入作業,直到完成 I/O 要求的足夠的資料或足夠的緩衝區空間。
需求
程序 |
必要的標頭檔 |
選擇性標頭 |
---|---|---|
_pipe |
<io.h> |
<fcntl.h>1 <errno.h>2, |
1 提供 _O_BINARY 和 _O_TEXT 定義。
2 errno 定義。
如需相容性詳細資訊,請參閱 相容性。
程式庫
所有的 C 執行階段程式庫 (C run-time libraries) 版本。
範例 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.
範例 2
這是一個基本的篩選應用程式。它會產生應用程式 crt_pipe_beeper,在建立直接產生的應用程式的 stdout 至篩選後的管道。篩選條件移除的 ASCII 7 (嗶聲) 字元。
// 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;
}
實際篩選應用程式:
// 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;
}
Output
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 對等用法
不適用。若要呼叫標準 C 函式,請使用 PInvoke。如需詳細資訊,請參閱平台叫用範例。