【linux】管道!!!

doctor_xiong發表於2018-03-12

程式間通訊的方式有:

  • 管道
  • 訊息佇列
  • 共享記憶體
  • 訊號量

    在這裡面管道是最古老的程式間通訊方式,管道又分為匿名管道和命名管道。
    匿名管道
    侷限性:

  • 只能夠在具有親緣關係的程式裡面使用
  • 管道提供流式服務
  • 管道的生命週期隨程式
  • 核心會對管道操作進行互斥和同步
  • 管道資料只能單向傳遞

    這裡寫圖片描述
    在匿名管道里面使用到的函式是int pipo(int fd[2]);
    fd[0]表示的是讀端
    fd[1]表示的是寫端

當需要兩個程式之間進行通訊的時候就可以將一個程式的讀或寫端的檔案關閉,那麼剩下的就是一個程式掌握的寫,一個程式掌握著讀,那麼這樣就可以在程式間進行通訊了。
例項:實現兩個程式間的通訊


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

int main(){
    int fd[2];
    char* buf = "nihao!\n";
    pid_t pid;
    if(pipe(fd) < 0){
        perror("pipe");
        exit(2);
    }
    if((pid = fork()) < 0){
        perror("fork");
        exit(1);
    }
    if(pid == 0){
        int i = 5;
        close(fd[0]);
        while(i--){
            sleep(1);
            write(fd[1],buf,strlen(buf));
        }
        close(fd[1]);
        exit(0);
    }
    else{
        char* output[1024] = {0};
        int r = 0;
        while(1){
            if(read(fd[0],output,1024) > 0){
                printf("%s",output);
            }
            else {
                exit(0);
            } 
        }
        close(fd[1]);
    }
    return 0;
}

命名管道

在匿名管道里面最大的侷限性就是程式間的通訊只能具有親緣關係的程式間才可以進行。但是在實際的應用中程式間的通訊往往並不只是在親緣程式間,這時候就需要使用命名管道來進行程式間的通訊。

原理:在啟動一個程式的時候就會在程式裡面開啟有相應的檔案,而每個程式裡面的開啟的檔案是獨立的,命名管道是通過管道檔案實現的,這裡的管道檔案是一個所有程式都共享的檔案,那麼這樣程式通過檔案的讀寫操作就可以進行程式間的通訊了。

這裡寫圖片描述
注:這裡的不同程式的檔案描述符不一定一樣

在建立命名管道檔案的時候可以使用mkfifo命令建立,同時如果實在程式裡面也可以使用函式建立
建立命名管道檔案的函式是int mkfifo(const char *pathname,int mode);

例項:實現兩個不相干程式間的通訊
1_exe.c

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

int main()
{
    char buf[1024] = {0};
    int fd = open("fifo",O_WRONLY);
    if(fd < 0){
        perror("open");
        return 1;
    }
    while(1){
        printf("Please Inter :>");
        fflush(stdout);
        ssize_t r = read(0,buf,sizeof(buf)-1);
        if(r < 0){
            perror("read");
            return 2;
        }
        else{
            write(fd,buf,strlen(buf));
        }
    }
    close(fd);
    return 0;
}

2_exe.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/types.h>

int main(){

    int fd;
    if(mkfifo("./fifo",0644) < 0)
    {
        perror("mkfifo");
        return 1;
    }
    fd = open("fifo",O_RDONLY);
    if(fd < 0){
        perror("open");
        return 1;
    }
    else{
        char buf[1024] = {0};
        while(1){
            memset(buf,0,sizeof(buf));
            ssize_t r = read(fd,buf,sizeof(buf)-1);
            if(r > 0){
                printf("Msg->:%s",buf);
            }
            else if(r == 0){
                printf("child is close!\n");
                return 0;
            }
            else{
                perror("read");
                return 1;
            }
        }
    }
    close(fd);
}

相關文章