IPC之FIFO 有名管道 詳解

2021-07-17 01:20:12 字數 3433 閱讀 1274

基本概念:

管道沒有名字,因此它們的最大劣勢是只能用於有乙個共同祖先程序的各個程序之間。我們無法在無親緣關係的程序間建立乙個管道並將它用作ipc管道(不考慮描述符傳遞)。

fifo指先進先出(first in,first out),它是乙個單向(半雙工)資料流。不同於管道的是,每個fifo有乙個路徑名與之關聯,從而允許無親緣關係的程序訪問同乙個fifo。fifo也稱為有名管道(named pipe)。

函式說明:

fifo由mkfifo函式建立

mkfifo(3)                  linux programmer's manual                 mkfifo(3)

name

mkfifo - make a fifo special file (a named pipe)

synopsis

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

返回:若成功則為0,若出錯則為-1
其中pathname是乙個普通的路徑名,它是該fifo的名字。

mode引數指定檔案許可權位,類似於open的第三個引數。

mkfifo函式已隱含指定o_creat | o_excl。也就是說,它要麼建立乙個新的fifo,要麼返回乙個eexist錯誤(如果所指定名字的fifo已經存在)。要開啟乙個已存在的fifo或建立乙個新的fifo,應先呼叫mkfifo,再檢查它是否返回eexist錯誤,若返回該錯誤則改為呼叫open。

在建立出乙個fifo後,它必須開啟來讀,或者開啟來寫,所用的可以是open函式,也可以是某個標準i/o開啟函式,例如open。fifo不能開啟來既讀又寫,因為它是半雙工的。

如果對管道或fifo呼叫lseek,那就返回espipe錯誤。

注意:如果當前尚沒有任何程序寫開啟某個fifo,那麼讀開啟該fifo的程序將阻塞。

同理,如果當前尚沒有任何程序讀開啟某個fifo,那麼寫開啟該fifo的程序將阻塞。

例子:

啟動兩個不同的程序,通過兩個管道來通訊,需要注意到兩個管道的讀寫順序在兩個程序中是不一樣的。

這裡的open開啟的檔案描述符預設是阻塞模式。

gcc fifo_server.c -o server

#include #include #include #include #include #include #include #include #define maxline 1024

#define fifo1 "/tmp/fifo.1"

#define fifo2 "/tmp/fifo.2"

void perror(const char *s)

void server(int readfd, int writefd)

; sprintf(buff, "hello world %d", i);

int n = write(writefd, buff, strlen(buff));

sleep(1);

}char buff[maxline] = ;

int n = read(readfd, buff, maxline);

if (n > 0)

}int main()

printf("create fifo success\n");

/* 要注意open的順序 */

readfd = open(fifo2, o_rdonly, 0);

writefd = open(fifo1, o_wronly, 0);

printf("open fifo success\n");

/* 讓fifo在程序結束後自動刪除 */

unlink(fifo1);

unlink(fifo2);

server(readfd, writefd);

return 0;

}

gcc fifo_client.c -o client

#include #include #include #include #include #include #include #include #define maxline 1024

#define fifo1 "/tmp/fifo.1"

#define fifo2 "/tmp/fifo.2"

void perror(const char *s)

void client(int readfd, int writefd)

; int n = read(readfd, buff, maxline);

if (n > 0)

}char *buff = "goodby server";

write(writefd, buff, strlen(buff));

}int main()

/* 要注意open的順序 */

writefd = open(fifo2, o_wronly);

readfd = open(fifo1, o_rdonly);

client(readfd, writefd);

return 0;

}

執行結果:

關於fifo的大小:

經過測試,unubtu 14下的fifo大小是64kb,與管道的大小一致。

如果請求寫入的資料的位元組數小於或等於pipe_buf,那麼write的操作保證的原子的。這意味著,如果有兩個程序差不多同時往同乙個管道或fifo寫,那麼或者先寫入來自第乙個程序的所有資料,再寫入來自第二個程序的所有資料,或者顛倒過來。系統不會互相混雜來自這兩個程序的資料。然而,如果請求寫入的資料的位元組數大於pipe_buf,那麼write操作不能保證是原子的。

可以通過getconf命令檢視pipe_buf的大小

關於資料永續性:當乙個管道或fifo的最後一次關閉發生時,仍在該管道或fifo上的資料將被丟棄。

關於更多:ipc之管道和fifo的額外屬性

參考:《unix網路程式設計》·卷2

end;

FIFO 有名管道

有名管道相關的關鍵概念 管道應用的乙個重大限制是它沒有名字,因此,只能用於具有親緣關係的程序間通訊,在有名管道 named pipe或fifo 提出後,該限制得到了克服。fifo不同於管道之處在於它提供乙個路徑名與之關聯,以fifo的檔案形式存在於檔案系統中。這樣,即 使與fifo的建立程序不存在親...

Linux 多程序 IPC之有名管道FIFO

命名管道也被稱為fifo檔案,是一種特殊的檔案。由於linux所有的事物都可以被視為檔案,所以對命名管道的使用也就變得與檔案操作非常統一。1 建立命名管道 用如下兩個函式中的其中乙個,可以建立命名管道。include include int mkfifo const char filename,mo...

21 有名管道fifo

1.特點 有名管道 在磁碟上有這樣乙個檔案,可通過命令ls l檢視字首帶p的檔案 偽檔案,在磁碟上大小永遠為0 在核心中有乙個對應的緩衝區 半雙工的通訊方式 預設阻塞 2.使用場景 沒有血緣關係的程序間通訊 3.建立方式 命令 mkfifo 管道名 函式 mkfifo 類似於mkdir 4.fifo...