天天看點

有名管道 有名管道

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。

有名管道

有名管道是獨立于程序存在的

有名管道可以看成是有檔案名辨別的一個管道,不同于管道之處在于它提供一個路徑名與之關聯,以FIFO的檔案形式存在于檔案系統中。FIFO一旦建立,open、write、read、close操作跟普通檔案一樣(不支援諸如lseek()等檔案定位操作)。

建立管道

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);

pathname:路徑名

mode:權限模式

類似的指令:mkfifo -m 模式 檔案名,如圖

有名管道 有名管道

删除管道

int unlink(const char *pathname);

open/read/write/close這幾個操作與普通檔案的操作一樣

阻塞/等待

讀端:open(O_RDONLY)  寫端:open(O_WRONLY)

注意:隻有讀端或者隻有寫端的時候,open函數都會阻塞

           寫端關閉:隻剩下讀端時,讀端傳回0

           讀端關閉:隻剩下寫端時,寫端會被禁止

代碼示範:

建立有名管道

#include<stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include<stdlib.h>

int main()

{

    if(mkfifo("myfifo", 0666) == -1)

    {   

        perror("mkfifo");

        exit(1);

    }   

    return 0;

}

寫管道

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<unistd.h>

#include<sys/stat.h>

#include<sys/types.h>

#include<fcntl.h>

#define N 64

int main()

{

    int fd;

    char *s;

    char buf[N];

    if((fd = open("myfifo", O_WRONLY)) == -1)

    {

        perror("open");

        exit(1);

    }

    while((s = fgets(buf, N, stdin)))

    {

        write(fd, buf, sizeof(buf));

        if(strncmp(buf, "quit", 4) == 0)

            break;

    }

    close(fd);

    return 0;

}

讀管道

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<unistd.h>

#include<sys/stat.h>

#include<sys/types.h>

#include<fcntl.h>

#define N 64

int main()

{

    int fd;

    ssize_t n;

    char buf[N];

    if((fd = open("myfifo", O_RDWR)) == -1)

    {

        perror("open");

        exit(1);

    }

    while(1)

    {

        if((n = read(fd, buf, N)) <= 0)

        {

            perror("read");

            exit(1);

        }

        if(strncmp(buf, "quit", 4) == 0)

            break;

        printf("%s", buf);

    }

    close(fd);

    return 0;

}

運作

有名管道 有名管道

注意:多個程序讀fifo,有名管道是一個隊列而不是一個普通檔案,寫端将位元組寫入隊列,而讀端從隊列的頭部移出位元組,每個讀端都會将資料移出隊列,是以如果想保證讀端都讀到資料,寫端必須要重寫資料,看圖

有名管道 有名管道

競态:

FIFO不會出現競态問題,read和write系統調用時原子操作。即讀取操作将管道清空,而寫入操作一次性将資料寫入或者将管道塞滿。在讀端和寫端連通之前,系統核心會将程序挂起。

繼續閱讀