_pipe

创建读写操作一个管道。

重要

此 API 不能在 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 使用按默认 value 模式变量 _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 运行库的所有版本。

示例 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。有关更多信息,请参见平台调用示例

请参见

参考

处理和环境控件

_open, _wopen