命名管道也被稱為fifo檔案,是一種特殊的檔案。由於linux所有的事物都可以被視為檔案,所以對命名管道的使用也就變得與檔案操作非常統一。
(1)建立命名管道
用如下兩個函式中的其中乙個,可以建立命名管道。
#include #include int mkfifo(const char *filename, mode_t mode);
int mknod(const char *filename, mode_t mode | s_ififo, (dev_t)0);
filname是指檔名,而mode是指定檔案的讀寫許可權。mknod是比較老的函式,而使用mkfifo函式更加簡單和規範,所以建議用mkfifo。
(2)開啟命名管道
和開啟其他檔案一樣,可以用open來開啟。通常有四種方法:
有兩點要注意:
1、就是程式不能以o_rdwr(讀寫)模式開啟fifo檔案進行讀寫操作,而其行為也未明確定義,因為如乙個管道以讀/寫方式開啟,程序就會讀回自己的輸出,同時我們通常使用fifo只是為了單向的資料傳遞。
2、就是傳遞給open呼叫的是fifo的路徑名,而不是正常的檔案。(如:const char *fifo_name = "/tmp/my_fifo"; )
3、第二個引數中的選項o_nonblock,選項o_nonblock表示非阻塞,加上這個選項後,表示open呼叫是非阻塞的,如果沒有這個選項,則表示open呼叫是阻塞的。
open(const char *path, o_rdonly);//1
open(const char *path, o_rdonly | o_nonblock);//2
open(const char *path, o_wronly);//3
open(const char *path, o_wronly | o_nonblock);//4
(3)阻塞問題
對於以唯讀方式(o_rdonly)開啟的fifo檔案,如果open呼叫是阻塞的(即第二個引數為o_rdonly),除非有乙個程序以寫方式開啟同乙個fifo,否則它不會返回;如果open呼叫是非阻塞的的(即第二個引數為o_rdonly | o_nonblock),則即使沒有其他程序以寫方式開啟同乙個fifo檔案,open呼叫將成功並立即返回。
對於以只寫方式(o_wronly)開啟的fifo檔案,如果open呼叫是阻塞的(即第二個引數為o_wronly),open呼叫將被阻塞,直到有乙個程序以唯讀方式開啟同乙個fifo檔案為止;如果open呼叫是非阻塞的(即第二個引數為o_wronly | o_nonblock),open總會立即返回,但如果沒有其他程序以唯讀方式開啟同乙個fifo檔案,open呼叫將返回-1,並且fifo也不會被開啟。
(4)使用fifo實現程序間的通訊
管道的寫入端從乙個檔案讀出資料,然後寫入寫管道。管道的讀取端從管道讀出後寫到檔案中。
fifowrite.c
#include #include #include #include #include #include #include #include int main()
}printf("process %d opening fifo o_wronly\n", getpid());
pipe_fd = open(fifo_name, open_mode);
printf("process %d result %d\n", getpid(), pipe_fd);
if(pipe_fd != -1)
bytes_read = read(data_fd, buffer, pipe_buf);
buffer[bytes_read] = '\0';
while(bytes_read > 0)
bytes_sent += res;
bytes_read = read(data_fd, buffer, pipe_buf);
buffer[bytes_read] = '\0';
}close(pipe_fd);
close(data_fd);
}else
exit(exit_failure);
printf("process %d finished\n", getpid());
exit(exit_success);
}
fiforead.c
#include #include #include #include #include #include #include #include int main()
printf("process %d result %d\n",getpid(), pipe_fd);
if(pipe_fd != -1)
while(res > 0);
close(pipe_fd);
close(data_fd);
}else
exit(exit_failure);
printf("process %d finished, %d bytes read\n", getpid(), bytes_read);
exit(exit_success);
}
(5)命名管道的安全問題
有一種情況是:乙個fifo檔案,有多個程序同時向同乙個fifo檔案寫資料,而只有乙個讀fifo程序在同乙個fifo檔案中讀取資料時,會發生資料塊的相互交錯。不同程序向乙個fifo讀程序傳送資料是很普通的情況。這個問題的解決方法,就是讓寫操作的原子化。系統規定:在乙個以o_wronly(即阻塞方式)開啟的fifo中, 如果寫入的資料長度小於等待pipe_buf,那麼或者寫入全部位元組,或者乙個位元組都不寫入。如果所有的寫請求都是發往乙個阻塞的fifo的,並且每個寫記請求的資料長度小於等於pipe_buf位元組,系統就可以確保資料決不會交錯在一起。
Linux程序通訊之有名管道
1 定義參照前文無名管道 2 特點 1 區別於無名,管道有名管道可以使互不相關的兩個程序通訊 在建立管道時,通過路徑 檔名來進行識別 2 建立有名管道後,程序可以將其作為檔案來進行讀寫 3 先進先出fifo。4 fifo在寫入的資料的位元組數小於或者等於pipe buf時,能夠保證write操作是原...
程序通訊之有名管道
程序通訊之有名管道 一 前言 我們前面部落格講過,父子程序之間,對於檔案操作的檔案操作符是共享的,而對於程序的全域性資料,堆區資料,棧區資料是不共享的,那麼程序之間到底是怎麼進行資訊的傳遞的呢,具體的實現,以及傳遞的過程是怎麼完成的呢,前面我們講過訊號在程序之間的使用,那也是一種程序之間資訊的傳遞。...
多程序通訊 IPC
ipc inter process communication 1 特點 2 主要api 1 建立管道 原型 int pipe int pipefd 2 引數 pipefd 做輸出引數使用,存放是管道的讀,寫檔案描述符。pipefd 0 存放讀,pipefd 1 存放寫 2 讀寫 把將管道當作檔案,...