Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Lập Trình C

Ống ẩn danh (Anonymous Pipe) trong Windows

Giới thiệu

Ống ẩn danh Windows là ống thông thường (ordinary pipes), đơn hướng, quan hệ cha-con, tương tự UNIX. Đọc/ghi bằng ReadFile()/WriteFile(). Tạo bằng CreatePipe() với 4 tham số: handle đọc, handle ghi, cấu trúc STARTUPINFO (kế thừa handle), kích thước ống.

Đặc điểm quan trọng

  • Windows yêu cầu chỉ định rõ thuộc tính kế thừa cho tiến trình con (khác UNIX)
  • Khởi tạo SECURITY_ATTRIBUTES cho phép kế thừa handle
  • Chuyển hướng stdin/stdout của tiến trình con đến handle đọc/ghi của ống
  • Cấm tiến trình con kế thừa handle ghi (vì ống bán song công)

Code tiến trình cha (Parent)

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define BUFFER_SIZE 25

int main() {
    HANDLE ReadHandle, WriteHandle;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    char message[BUFFER_SIZE] = "Greetings";
    DWORD written;

    SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
    ZeroMemory(&pi, sizeof(pi));

    if (!CreatePipe(&ReadHandle, &WriteHandle, &sa, 0)) {
        fprintf(stderr, "Create Pipe Failed");
        return 1;
    }

    GetStartupInfo(&si);
    si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    si.hStdInput = ReadHandle;           // Con đọc từ ống
    si.dwFlags = STARTF_USESTDHANDLES;
    SetHandleInformation(WriteHandle, HANDLE_FLAG_INHERIT, 0); // Cấm con kế thừa ghi

    CreateProcess(NULL, "child.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);

    CloseHandle(ReadHandle);  // Cha không đọc
    WriteFile(WriteHandle, message, BUFFER_SIZE, &written, NULL);
    CloseHandle(WriteHandle);

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return 0;
}

Code tiến trình con (Child)

#include <stdio.h>
#include <windows.h>

#define BUFFER_SIZE 25

int main() {
    HANDLE ReadHandle;
    CHAR buffer[BUFFER_SIZE];
    DWORD read;

    ReadHandle = GetStdHandle(STD_INPUT_HANDLE);  // Lấy handle stdin (đã chuyển hướng)
    if (ReadFile(ReadHandle, buffer, BUFFER_SIZE, &read, NULL))
        printf("child read %s", buffer);
    else
        fprintf(stderr, "Error reading from pipe");
    return 0;
}

Luồng dữ liệu

Parent: WriteHandle → WriteFile() → Pipe → ReadHandle → Child: ReadFile() → buffer