_pipe
읽기 및 쓰기용 파이프를 만듭니다.
Important
이 API는 Windows 런타임에서 실행되는 애플리케이션에서 사용할 수 없습니다. 자세한 내용은 유니버설 Windows 플랫폼 앱에서 지원되지 않는 CRT 함수를 참조하세요.
구문
int _pipe(
int *pfds,
unsigned int psize,
int textmode
);
매개 변수
pfds
읽기 및 쓰기 파일 설명자를 저장할 두 int
개의 배열에 대한 포인터입니다.
psize
예약할 메모리의 양입니다.
textmode
파일 모드입니다.
반환 값
정상적으로 실행되는 경우 0을 반환합니다. 오류를 나타내려면 -1을 반환합니다. 오류 시 errno
는 다음 값 중 하나로 설정됩니다.
EMFILE
- 파일 설명자를 더 이상 사용할 수 없음을 나타냅니다.ENFILE
- 시스템 파일 테이블 오버플로를 나타냅니다.EINVAL
- 배열pfds
가 null 포인터이거나textmode
에 대한 잘못된 값이 전달되었음을 나타냅니다.
이러한 코드 및 기타 반환 코드에 대한 자세한 내용은 , _doserrno
및 _sys_nerr
_sys_errlist
를 참조하세요.errno
설명
_pipe
함수는 프로그램이 다른 프로그램에 정보를 전달하는 데 사용하는 인위적인 I/O 채널인 파이프를 만듭니다. 파이프는 파일 포인터, 파일 설명자 또는 둘 다 있기 때문에 파일과 유사합니다. 또한 표준 라이브러리 입력 및 출력 함수를 사용하여 읽거나 쓸 수 있습니다. 그러나 파이프는 특정 파일 또는 디바이스를 나타내지 않습니다. 대신 전적으로 운영 체제에 의해 제어되며 프로그램의 자체 메모리와는 독립적인 임시 스토리지를 나타냅니다.
_pipe
는 _open
과 비슷하지만 읽기 및 쓰기용으로 파이프를 열며 하나가 아닌 두 개의 파일 설명자를 반환합니다. 프로그램은 파이프 양쪽을 모두 사용할 수도 있고 필요하지 않은 쪽을 닫을 수도 있습니다. 예를 들어 Windows의 명령 프로세서는 PROGRAM1 | PROGRAM2
등의 명령을 실행할 때 파이프를 만듭니다.
PROGRAM1
의 표준 출력 설명자는 파이프의 쓰기 설명자에 연결됩니다. PROGRAM2
의 표준 입력 설명자는 파이프의 읽기 설명자에 연결됩니다. 이 첨부 파일은 다른 프로그램에 정보를 전달하는 임시 파일을 만들 필요가 없습니다.
_pipe
함수는 파이프에 대한 파일 설명자 두 개를 pfds
인수에서 반환합니다. 요소 pfds
[0]은 읽기 설명자를 포함하며 요소 pfds
[1]은 쓰기 설명자를 포함합니다. 파이프 파일 설명자도 다른 파일 설명자와 같은 방식으로 사용됩니다. (하위 수준의 입력 및 출력 함수 _read
이며 _write
파이프에서 읽고 쓸 수 있습니다.) 파이프 끝 조건을 검색하려면 읽은 바이트 수로 0을 반환하는 요청을 확인 _read
합니다.
psize
인수는 파이프용으로 예약할 메모리의 양(바이트)을 지정합니다. textmode
인수는 파이프에 대한 변환 모드를 지정합니다. 매니페스트 상수 _O_TEXT
는 ANSI 텍스트 변환을 지정하고 상수 _O_BINARY
는 이진 변환을 지정합니다. 텍스트 및 이진 모드에 대한 설명은 <_wfopen
a0/>를 참조fopen
하세요. 인수가 textmode
0 _pipe
이면 기본 모드 변수_fmode
로 지정된 기본 변환 모드를 사용합니다.
다중 스레드 프로그램에서는 잠금이 수행되지 않습니다. 반환되는 파일 설명자는 새로 열리며 호출이 완료될 때까지 _pipe
스레드에서 참조해서는 안 됩니다.
부모 프로세스와 자식 프로세스 간의 통신에 _pipe
함수를 사용하려면 각 프로세스의 파이프에서 설명자가 하나만 열려 있어야 합니다. 열려 있는 설명자는 서로 반대여야 합니다. 즉, 부모 프로세스에서 읽기 설명자가 열려 있으면 자식 프로세스에서는 쓰기 설명자가 열려 있어야 합니다. 플래그textmode
에 비트 "or"(|
)를 사용하는 것이 가장 쉽습니다_O_NOINHERIT
. 그런 후에 _dup
또는 _dup2
를 사용하여 자식 프로세스에 전달할 파이프 설명자의 상속 가능한 복사본을 만듭니다. 마지막으로 원래 설명자를 닫고 자식 프로세스를 생성합니다. 생성 호출이 종료되면 부모 프로세스에서 중복 설명자를 닫습니다. 자세한 내용은 이 문서 뒷부분의 예제 2를 참조하세요.
Windows 운영 체제에서는 모든 설명자가 닫히면 파이프가 삭제됩니다. (파이프의 모든 읽기 설명자가 닫힌 경우 파이프에 쓰면 오류가 발생합니다.) I/O 요청을 완료하기에 충분한 데이터 또는 충분한 버퍼 공간이 있을 때까지 파이프에 대한 모든 읽기 및 쓰기 작업이 대기합니다.
기본적으로 이 함수의 전역 상태는 애플리케이션으로 범위가 지정됩니다. 이 동작을 변경하려면 CRT 전역 상태를 참조하세요.
요구 사항
루틴에서 반환된 값 | 필수 헤더 | 선택적 헤더 |
---|---|---|
_pipe |
<io.h> |
<fcntl.h> ,1 <errno.h> 2 |
1 For _O_BINARY
및 _O_TEXT
definitions.
정의 2 errno
개.
호환성에 대한 자세한 내용은 호환성을 참조하세요.
라이브러리
모든 버전의 C 런타임 라이브러리입니다.
예제 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;
}
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...