[Windows进程间通信] 匿名管道

[Windows进程间通信] 匿名管道

参考链接: https://blog.csdn.net/weixin_41875267/article/details/108466758

通过匿名管道可以实现两个进程间的数据传输

使用管道的缺点:

1. 只能用于有父子关系的进程,且管道可能遇到阻塞问题

2. 只能用于本地的进程间通信,不能跨机器

主要用到的API

BOOL CreatePipe(  [out]          PHANDLE               hReadPipe,  [out]          PHANDLE               hWritePipe,  [in, optional] LPSECURITY_ATTRIBUTES lpPipeAttributes,  [in]           DWORD                 nSize);BOOL ReadFile(  [in]                HANDLE       hFile,  [out]               LPVOID       lpBuffer,  [in]                DWORD        nNumberOfBytesToRead,  [out, optional]     LPDWORD      lpNumberOfBytesRead,  [in, out, optional] LPOVERLAPPED lpOverlapped);BOOL WriteFile(  [in]                HANDLE       hFile,  [in]                LPCVOID      lpBuffer,  [in]                DWORD        nNumberOfBytesToWrite,  [out, optional]     LPDWORD      lpNumberOfBytesWritten,  [in, out, optional] LPOVERLAPPED lpOverlapped);

使用匿名管道时,先用CreatePipe创建管道,管道有一个读句柄和一个写句柄。随后可以创建子进程,通过修改子进程的标准输入输出实现与子进程的通信。如父进程通过写句柄写入数据,子进程通过读句柄读取数据。常见的情况是创建2个管道,一个用于父进程向子进程写入,一个用于子进程向父进程写入。

以下是示例:

父进程创建子进程并向子进程写数据,子进程读取到数据后,将内容再输出到父进程的窗口上

父进程:

#include <windows.h>#include <iostream>using namespace std;HANDLE hRead;HANDLE hWrite;BOOL CreateChildProcess() {    SECURITY_ATTRIBUTES sa;    sa.bInheritHandle = TRUE;    sa.lpSecurityDescriptor = NULL;    sa.nLength = sizeof(SECURITY_ATTRIBUTES);    if (!CreatePipe(&hRead, &hWrite, &sa, 0)) {        printf("Failed to create pipe.");        return FALSE;    }    STARTUPINFO si;    PROCESS_INFORMATION pi;    ZeroMemory(&si, sizeof(STARTUPINFO));    si.cb = sizeof(STARTUPINFO);    si.dwFlags = STARTF_USESTDHANDLES;    si.hStdInput = hRead; // Child process read from this handle rather than std input handle    si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); // Child process also outputs content to parent's window    if (FALSE == CreateProcess("child.exe",        NULL,         NULL,         NULL,         TRUE,         0,         NULL,         NULL,         &si,         &pi)) {        auto err = GetLastError();        CloseHandle(hRead);        CloseHandle(hWrite);        return FALSE;    }    else {                CloseHandle(pi.hProcess);        CloseHandle(pi.hThread);    }    return TRUE;}#define BUFFER_SIZE 4096void SendData() {    char data[BUFFER_SIZE] = { 0 };    while (true) {        scanf_s("%s", data, BUFFER_SIZE);        DWORD dwWrite = 0;        if (!WriteFile(hWrite, data, strnlen_s(data, BUFFER_SIZE) + 1, &dwWrite, NULL)) {            printf_s("Failed to write to child process.");        }        if (strcmp(data, "quit") == 0) {            break;        }    }}int main() {    if (CreateChildProcess()) {        SendData();    }    return 0;}

子进程:

#include <windows.h>#include <iostream>using namespace std;#define BUFFER_SIZE 4096int main() {    auto hRead = GetStdHandle(STD_INPUT_HANDLE); // This has been replaed by pipe read handle    char data[BUFFER_SIZE] = { 0 };    DWORD dwRead = 0;    while (true) {        ReadFile(hRead, data, BUFFER_SIZE, &dwRead, NULL);        if (strcmp(data, "quit") == 0) {            break;        }        printf_s("child process: %s", data);    }    return 0;}

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部