Windows匿名管道
Windows匿名管道实际上是普通管道,它们的行为与UNIX管道类似:它们是单向的,并且在通信进程之间采用父子关系。另外,可以使用普通的ReadFile()和WriteFile()函数来完成对管道的读取和写入。WindowsAPI使用CreatePipe()函数创建管道,该函数传递了四个参数。这些参数为
阅读和
写入管道
STARTUPINFO结构的实例,用于指定子进程将继承管道的句柄。
可以指定管道的大小(以字节为单位)。
与UNIX系统不同,Windows要求程序员指定子进程将继承哪些属性。这是通过首先初始化SECURITYATTRIBUTES结构来允许继承句柄,然后将子进程的标准输入或标准输出的句柄重定向到管道的读取或写入句柄来实现的。由于孩子将从管道中读取数据,因此父级必须将孩子的标准输入重定向到管道的读取句柄。由于管道是半双工的,因此需要禁止孩子继承管道的写端。
在下面的代码中,我们可以看到父进程创建了一个匿名管道以与其子进程进行通信-
示例
#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匿名管道-子进程