Windows匿名管道


Windows匿名管道实际上是普通管道,其行为与UNIX中的对应物类似:它们是单向的,并且在通信进程之间采用父子关系。此外,可以使用普通的ReadFile()和WriteFile()函数来读写管道。Windows API使用CreatePipe()函数创建管道,该函数传递四个参数。这些参数为

  • 读和

  • 写管道提供单独的句柄

  • STARTUPINFO结构的一个实例,用于指定子进程要继承管道的句柄。

  • 可以指定管道的尺寸(以字节为单位)。

与UNIX系统不同,Windows要求程序员指定子进程将继承哪些属性。这是通过首先初始化SECURITY_ATTRIBUTES结构(允许继承句柄),然后将子进程的标准输入或标准输出句柄重定向到管道的读或写句柄来实现的。由于子进程将从管道读取数据,因此父进程必须将子进程的标准输入重定向到管道的读句柄。由于管道是半双工的,因此需要禁止子进程继承管道的写端。

在下面的代码中,我们可以看到一个父进程创建了一个匿名管道,用于与其子进程通信:

示例

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define BUFFER SIZE 25
int main(VOID) {
   HANDLE ReadHandle, WriteHandle;
   STARTUPINFO si;
   PROCESS INFORMATION pi;
   char message[BUFFER SIZE] = "Greetings";
   DWORD written;
   /* set up security attributes to allow pipes to be inherited */
   SECURITY ATTRIBUTES sa = {sizeof(SECURITY ATTRIBUTES), NULL, TRUE};
   /* allocate memory */
   ZeroMemory(π, sizeof(pi));
   /* create the pipe */
   if (!CreatePipe(&ReadHandle, &WriteHandle, &sa, 0)) {
   fprintf(stderr, "Create Pipe Failed"); return 1; }
   /* establishing the START INFO structure for the child process*/
   GetStartupInfo(&si);
   si.hStdOutput = GetStdHandle(STD OUTPUT HANDLE);
   /* redirecting standard input to the read end of the pipe */
   si.hStdInput = ReadHandle;
   si.dwFlags = STARTF USESTDHANDLES;
   /* don’t allow the child inheriting the write end of pipe */
   SetHandleInformation(WriteHandle, HANDLE FLAG INHERIT, 0);
   /* create the child process */
   CreateProcess(NULL, "child.exe", NULL, NULL, TRUE, /* inherit handles */ 0, NULL, NULL, &si, π);
   /* close the unused end of the pipe */ CloseHandle(ReadHandle);
   /* the parent writes to the pipe */
   if(!WriteFile(WriteHandle, message, BUFFER SIZE, &written, NULL))
   fprintf(stderr, "Error writing to pipe.");
   /* close the write end of the pipe */ CloseHandle(WriteHandle);
   /* wait for the child to exit */ WaitForSingleObject(pi.hProcess,INFINITE);        
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);
   return 0;
}

Windows匿名管道 - 父进程

父进程首先关闭其未使用的管道读端,然后写入管道。从管道读取数据的子进程显示在下面的代码中:

#include<stdio.h>
#include<windows.h>
#define BUFFER SIZE 25
int main(VOID){
   HANDLE Readhandle;
   CHAR buffer[BUFFER SIZE];
   DWORD read;
   /* getting the read handle of the pipe */
   ReadHandle = GetStdHandle(STD INPUT HANDLE);
   /* the child reads from the pipe */
   if (ReadFile(ReadHandle, buffer, BUFFER SIZE, &read, NULL))
      printf("child read %s", buffer);
   else
      fprintf(stderr, "Error reading from pipe");
   return 0;
}

Windows匿名管道 - 子进程

更新于:2019年10月11日

954 次浏览

开启你的职业生涯

完成课程获得认证

开始学习
广告
© . All rights reserved.