天天看點

Linux程序間通信之管道

1,程序間通信 (IPC ) Inter-Process Communication

  比較好了解概念的就是程序間通信就是在不同程序之間傳播或交換資訊。

2,linux下IPC機制的分類:管道、信号、共享記憶體、消息隊列、信号量、套接字

3,這篇主要說說管道:本質是檔案,其他理論什麼的網上已經有一大堆了,我就隻寫一點用法吧。

3.1 特點

     1)管道是最古老的IPC,但目前很少使用

     2)以檔案做互動的媒介,管道分為有名管道和無名管道

     3)曆史上的管道通常是指半雙工管道

3.2 管道:有兩種形式,指令行和非指令行

(1)指令行:

        mkfifo testfifo

        echo "testfifo" >fifo

        cat fifo

Linux程式間通信之管道

(2)非指令行:這裡又分有名管道和無名管道

程式設計模型:程序A建立管道(mkfifo) -> 程序A寫打開管道(open) -> 程序B讀打開管道(open) -> 程序A開始往管道裡寫資料(write) ->

       程序B從管道中讀資料(read) -> 程序A關閉管道(close) -> 程序B關閉管道(close) -> 删除管道(unlink)

有名管道(執行個體):

程序A:

#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>

#define PIPENAME "pipetest"

int main()
{
    // 建立管道
    if(mkfifo(PIPENAME, 0666) < 0)
    {
        perror("mkfifo");
        return -1;
    }

    // 寫打開管道 
    int fd = open(PIPENAME, O_WRONLY);
    if(-1 == fd)
    {
        perror("open");
        return -1;
    }

    unlink(PIPENAME);

    int i = 0;
    for(i = 0; i < 10; i++)
    {
        write(fd, &i, sizeof(i));
        printf("%d\n", i);
        sleep(1); // 這個是以秒為機關挂起
    }

    // 關閉管道
    close(fd);

    return 0;

}      

程序B:

#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>

#define PIPENAME "pipetest"

int main()
{
    // 讀打開管道
    int fd = open(PIPENAME, O_RDONLY);
    if(-1 == fd)
    {
        perror("open");
        return -1;
    }

    int num = 0;
    int i = 0;
    for(i = 0; i < 10; i++)
    {
        read(fd, &num, sizeof(int));
        printf("%d\n", num);
        fflush(stdout); // 強制重新整理輸出緩沖區
    }

    printf("\n");
    close(fd);

    return 0;

}      

運作效果如下:

Linux程式間通信之管道

開另外一個終端,運作讀程序

Linux程式間通信之管道

無名管道:适用于父子程序之間的通信

     int pipe(int pipefd[2]):該函數在核心中建立管道檔案,通過輸出參數pipefd傳回兩個檔案描述符,其中pipefd[0]用于讀,pipefd[1]用于寫。

注意:

  寫資料的程序關閉讀端pipefd[0]

      讀資料的程序關閉寫端pipefd[1]

執行個體:

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>

int main()
{
    int fd[2]; // 用來儲存檔案描述符
    pipe(fd);

    pid_t pid = fork();// 建立程序
    if(pid > 0)
    {
        // 父程序寫管道,需要關閉讀端
        close(fd[0]);
        int i = 0;
        for(i=10; i<20; i++)
        {
            write(fd[1], &i, sizeof(int));
            sleep(1);
        }

        close(fd[1]);// 關閉寫端
        exit(0);
    }

    // 子程序讀管道
    close(fd[1]); // 先關閉寫端 
    int x;
    int i = 0;
    for(; i<10; i++)
    {
        read(fd[0], &x, sizeof(int));
        printf("%d ", x);
        setbuf(stdout, NULL);
    }
    close(fd[0]);
    printf("\n");

    return 0;
}      
Linux程式間通信之管道

繼續閱讀