匿名管道

匿名管道是計算機進程間的一種單工先進先出通信機制。全雙工通信通常需要兩個匿名管道。

典型場景為父進程創建匿名管道,然後創建一批子進程繼承了這個匿名管道。由於這是未命名的管道,只能在本地計算機中使用,而不可用於網絡間的通信。匿名管道並不支持異步讀、寫操作。

Unix

管道 (Unix)類Unix系統上使用極其廣泛的進程間傳統通信機制。使用pipe 系統調用創建新的管道並返回一對文件描述符指向管道的讀終端與寫終端。

Windows操作系統

使用CreatePipe創建匿名管道。使用ReadFileWriteFile函數來讀寫管道。讀寫操作總是阻塞式。[1]新建進程可繼承管道句柄。

讀管道時收到一個end-of-file,意味着管道的寫端句柄已經關閉。

例子

//  父进程
#include <windows.h>
int main()
{
    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,   // No module name (use command line)
		(LPSTR)(LPCSTR)"Client.exe",        // Command line			
		NULL,           // Process handle not inheritable
		NULL,           // Thread handle not inheritable
		FALSE,          // Set handle inheritance to FALSE
		0,              // No creation flags
		NULL,           // Use parent's environment block
		NULL,           // Use parent's starting directory 
		&si,            // Pointer to STARTUPINFO structure
		&pi )           // Pointer to PROCESS_INFORMATION structure 
    if (bRet == TRUE)  
        printf("成功创建子进程!\n");
    else
        printf("创建子进程失败,错误代码:%d\n", GetLastError());
    SetStdHandle(STD_OUTPUT_HANDLE, hTemp); // 恢复本进程的标准输出
    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());
    return 0;
}
//子进程的标准输出实际上已经重定向到匿名管道写端
#include <stdio.h>
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;
}

參見

參考文獻

  1. ^ Anonymous Pipe Operations. MSDN. [2010-02-27]. (原始內容存檔於2011-06-05). Asynchronous (overlapped) read and write operations are not supported by anonymous pipes. 
  • Hart, Johnson M. Windows System Programming, Third Edition. Addison-Wesley, 2005. ISBN 0-321-25619-0
  • pipe(7) - Linux man page. [2010-02-27]. (原始內容存檔於2010-03-23).