匿名管道程序示例
总的来说,匿名管道程序是比较简单的。在下面将要给出的程序示例中,将由父进程(管道服务器)创建一个子进程(管道客户机),子进程回见个其全部的标准输出发送到匿名管道中,父进程再从管道读取数据,一直到子进程关闭管道的写句柄。其中,匿名管道服务器程序的实现清单如下:
STARTUPINFO si; PROCESS_INFORMATION pi; char ReadBuf[100]; DWORD ReadNum; HANDLE hRead; // 管道读句柄 HANDLE hWrite; // 管道写句柄 BOOL bRet = CreatePipe(&hRead, &hWrite, NULL, 0); // 创建匿名管道 if (bRet == TRUE) printf("成功创建匿名管道!\n"); else printf("创建匿名管道失败,错误代码:%d\n", GetLastError()); // 得到本进程的当前标准输出 HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE); // 设置标准输出到匿名管道 SetStdHandle(STD_OUTPUT_HANDLE, hWrite); GetStartupInfo(&si); // 获取本进程的STARTUPINFO结构信息 bRet = CreateProcess(NULL, "Client.exe", NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi); // 创建子进程 SetStdHandle(STD_OUTPUT_HANDLE, hTemp); // 恢复本进程的标准输出 if (bRet == TRUE) // 输入信息 printf("成功创建子进程!\n"); else printf("创建子进程失败,错误代码:%d\n", GetLastError()); CloseHandle(hWrite); // 关闭写句柄 // 读管道直至管道关闭 while (ReadFile(hRead, ReadBuf, 100, &ReadNum, NULL)) { ReadBuf[ReadNum] = '\0'; printf("从管道[%s]读取%d字节数据\n", ReadBuf, ReadNum); } if (GetLastError() == ERROR_BROKEN_PIPE) // 输出信息 printf("管道被子进程关闭\n"); else printf("读数据错误,错误代码:%d\n", GetLastError()); |
在本示例中,将当前进程的标准输出设置为使用匿名管道,再创建子进程,子进程将继承父进程的标准输出,然后再将父进程的标准输出恢复为其初始状态。于是父进程便可从管道读取数据,直到有错误发生或关闭管道写入端的所有句柄。创建的子进程只是向标准输出和标准错误发送一些文本信息,其中发送给标准输出的文本将重定向输出到管道,发送给标准错误的文本将不改变输出。下面给出子进程的实现代码:
int main(int argc, char* argv[]) { for (int i = 0; i < 100; i++) // 发送一些数据到标准输出和标准错误 { printf("i = %d\n", i); // 打印提示 cout << "标准输出:" << i << endl; // 打印到标准输出 cerr << "标准错误:" << i << endl; // 打印到标准错误 } return 0; } |
|