程序間通訊(1)-管道

lethe1203發表於2024-04-04
匿名管道(Anonymous Pipe)和有名管道(Named Pipe,也稱為FIFO)是兩種不同的程序間通訊方式,它們有以下主要區別:
  1. 命名和使用方式:
  • 匿名管道沒有名字,只能在具有親緣關係的程序之間使用,通常是在呼叫pipe()函式後直接使用,無需其他步驟。
  • 有名管道有一個檔名,它在檔案系統中有一個路徑,不限於親緣關係的程序之間使用,可以透過檔案系統路徑來訪問。它們由mkfifo()函式建立,並可以透過檔案系統進行訪問。
  1. 永續性:
  • 匿名管道在建立它們的程序終止時自動銷燬,因此只存在於建立它們的程序生命週期內。
  • 有名管道在檔案系統中存在,即使建立它們的程序終止,它們也可以被其他程序訪問,直到顯式地被刪除或檔案系統解除安裝。
  1. 通訊方式:
  • 匿名管道只能支援單向通訊,通常是用於父子程序之間的通訊。
  • 有名管道支援雙向通訊,可以被不相關的程序之間使用。
  1. 程序間關係:
  • 匿名管道通常用於具有父子關係的程序間通訊,因為它們是透過fork()建立的子程序繼承的。
  • 有名管道可以用於任意兩個程序間的通訊,只要它們能夠訪問相同的有名管道檔案。

匿名管道demo如下:

pipefd[0]只讀不寫,pipefd[1]只寫不讀
#include <stdlib.h>
#include <unistd.h>

#define BUFFER_SIZE 25

int main() {
    char buffer[BUFFER_SIZE];
    int pipefd[2]; // 用於存放管道的檔案描述符,pipefd[0]表示讀取端,pipefd[1]表示寫入端
    pid_t pid;

    // 建立管道
    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    // 建立子程序
    pid = fork();

    if (pid < 0) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (pid > 0) { // 父程序
        close(pipefd[0]); // 關閉讀取端,父程序只負責寫入資料

        printf("Parent process is writing to the pipe...\n");
        write(pipefd[1], "Hello from parent process!", 26);

        close(pipefd[1]); // 寫入完成後關閉寫入端
    } else { // 子程序
        close(pipefd[1]); // 關閉寫入端,子程序只負責讀取資料

        printf("Child process is reading from the pipe...\n");
        read(pipefd[0], buffer, BUFFER_SIZE);
        printf("Child process received: %s\n", buffer);

        close(pipefd[0]); // 讀取完成後關閉讀取端
    }

    return 0;
}
執行結果如下:
0

有名管道demo如下:

程序1:寫入資料到有名管道
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#define BUFFER_SIZE 25
#define FIFO_FILE "/tmp/myfifo"

int main() {
    char buffer[BUFFER_SIZE];
    int fd;

    // 建立有名管道
    mkfifo(FIFO_FILE, 0666);

    // 開啟有名管道以寫入資料
    fd = open(FIFO_FILE, O_WRONLY);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 寫入資料到管道
    printf("Process 1 is writing to the named pipe...\n");
    write(fd, "Hello from Process 1!", 21);
    printf("Process 1 wrote: Hello from Process 1!\n");

    // 關閉管道
    close(fd);

    return 0;
}

程序2:從有名管道讀取資料
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#define BUFFER_SIZE 25
#define FIFO_FILE "/tmp/myfifo"

int main() {
    char buffer[BUFFER_SIZE];
    int fd;

    // 建立有名管道
    mkfifo(FIFO_FILE, 0666);

    // 開啟有名管道以讀取資料
    fd = open(FIFO_FILE, O_RDONLY);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 從管道中讀取資料
    printf("Process 2 is reading from the named pipe...\n");
    read(fd, buffer, BUFFER_SIZE);
    printf("Process 2 received: %s\n", buffer);

    // 關閉管道
    close(fd);

    return 0;
}

執行結果如下:
0

相關文章