_pipe
Cria um pipe para ler e gravar.
Importante |
---|
Este API não pode ser usado em aplicativos executados em Tempo de Execução do Windows.Para obter mais informações, consulte Funções de CRT não suportadas com /ZW. |
int _pipe( int *pfds, unsigned int psize, int textmode );
Parâmetros
pfds[2]
Matriz para armazenar a leitura e gravação descritores de arquivo.psize
Quantidade de memória para a reserva.textmode
Modo de Arquivo.
Valor de retorno
Retorna 0 se com êxito.Retorna – 1 para indicar um erro.No erro, errno é definida como um desses valores:
EMFILE, que indica que não mais arquivo descritor está disponível.
ENFILE, que indica um estouro de sistema-Arquivo- tabela.
EINVAL, que indica que a matriz pfds é um ponteiro zero ou que um valor inválido para textmode esteve passado.
Para obter mais informações sobre esses e outros códigos de retorno, consulte errno, _doserrno, _sys_errlist e _sys_nerr.
Comentários
A função de _pipe cria um pipe, que é um canal de E/S que artificialmente um programa usa para passar informações para outros programas.Um pipe é semelhante a um arquivo porque tem um ponteiro de arquivo, um arquivo descritor, ou ambos, e pode ser lido ou gravado da usar as funções padrão de entrada e saída da biblioteca.No entanto, um pipe não representa um arquivo ou um dispositivo específico.Em vez disso, representa o armazenamento temporário na memória que é independente de própria memória do programa e é inteiramente controlado pelo sistema operacional.
_pipe é semelhante a _open mas abre-se o pipe para ler e gravar e retorna dois descritores de arquivo em vez de um.O programa pode usar ambos os lados de pipe ou fechar o que não precisa.Por exemplo, o processador de comando no Windows cria um pipe quando executa um comando como PROGRAM1 | PROGRAM2.
O descritor padrão de saída de PROGRAM1 é anexado ao descritor de gravação de pipe.O descritor padrão de entrada de PROGRAM2 é anexado ao descritor de leitura de pipe.Isso elimina a necessidade de criar arquivos temporários para passar informações para outros programas.
A função de _pipe returna dois descritores de arquivo para o pipe no argumento de pfds .O elemento 0 pfds[] contém o descritor de leitura, e o elemento 1 pfds[] contém o descritor de gravação.Descritores de arquivo de pipe são utilizados da mesma maneira que outros descritores de arquivo.(As funções de baixo nível _read e _write de entrada e saída podem ler e escrever em um pipe.) Para detectar a condição no final do ciclo, verificar uma solicitação de _read que retorna 0 como o número de bytes.
O argumento de psize especifica a quantidade de memória, em bytes, para reservar o pipe.O argumento de textmode especifica o modo de tradução para o pipe._O_TEXT constante manifesto especifica uma conversão de texto, e _O_BINARY constante especifica a conversão binário.(Consulte fopen, _wfopen para obter uma descrição de modos de texto e de binário.) Se o argumento de textmode é 0, _pipe usar o modo padrão de conversão que é especificado pela variável _fmodede modo padrão.
Em programas multi-thread, nenhum bloqueio é executado.Descritores de arquivo que são retornados recentemente estão abertos e não devem ser referenciados por qualquer segmento até após a chamada de _pipe concluída.
Para usar a função de _pipe para se comunicar entre um processo pai e um processo filho, cada processo deve ter apenas um descritor aberto no pipe.Descritores devem ser opostos: se o pai tiver um descritor de leitura aberto, então o filho deve ter um descritor de gravação aberto.A maneira mais fácil para fazer isso é a OR (|o sinalizador) de _O_NOINHERIT com textmode.Em seguida, use _dup ou _dup2 criar uma cópia herdável de descritor de pipe que você deseja passar para o filho.Feche o descritor original, e desovar no processo filho.O retorno de chamada de ova, feche o descritor duplicado no processo pai.Para mais informações, consulte o exemplo neste artigo 2 posteriormente.
No sistema operacional Windows, um pipe é destruído quando todos os seus descritores foram fechados.(Se todos os descritores no pipe foram fechados, então gravação para o pipe causa um erro.) Todas as operações de leitura e gravação no pipe espera até que haja suficiente dados ou espaço suficiente de buffer para concluir a solicitação de E/S.
Requisitos
Rotina |
Cabeçalho necessário |
Cabeçalho opcional |
---|---|---|
_pipe |
<io.h> |
<fcntl.h>, 1 <errno.h>2 |
1 Para _O_BINARY e definições de _O_TEXT .
2 definições de errno .
Para mais informações, consulte Compatibilidadede compatibilidade.
Bibliotecas
Todas as versões de Bibliotecas em tempo de execução de C.
Exemplo 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 ) );
}
}
}
A saída de exemplo
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.
Exemplo 2
Este é um aplicativo básico de filtro.Desova o crt_pipe_beeper do aplicativo depois que cria um pipe que direciona o stdout do aplicativo desovado para o filtro.O filtro remove caracteres ASCII 7 (do bipe).
// 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;
}
O aplicativo real de filtro:
// 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;
}
Saída
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...
Equivalência do .NET Framework
Não aplicável. Para chamar a função padrão de C, use PInvoke. Para obter mais informações, consulte Exemplos de invocação de plataforma.