管道是一種把兩個進程之間的標準輸入和標準輸出鏈接起來的機制,從而提供一種讓多個進程間通訊的方法,當進程建立管道時,每次html
都須要提供兩個文件描述符來操做管道。其中一個對管道進行寫操做,另外一個對管道進行讀操做。對管道的讀寫與通常的IO系統函數一數組
致,使用write()函數寫入數據,使用read()讀出數據。服務器
#include<unistd.h>函數
int pipe(int filedes[2]);ui
返回值:成功,返回0,不然返回-1。參數數組包含pipe使用的兩個文件的描述符。fd[0]:讀管道,fd[1]:寫管道。spa
必須在fork()中調用pipe(),不然子進程不會繼承文件描述符。兩個進程不共享祖先進程,就不能使用pipe。可是可使用命名管道。.net
當管道進行寫入操做的時候,若是寫入的數據小於128K則是非原子的,若是大於128K字節,緩衝區的數據將被連續地寫入3d
管道,直到所有數據寫完爲止,若是沒有進程讀取數據,則將一直阻塞,以下:unix
在上例程序中,子進程一次性寫入128K數據,當父進程將所有數據讀取完畢的時候,子進程的write()函數才結束阻塞而且code
返回寫入信息。
命名管道FIFO
管道最大的劣勢就是沒有名字,只能用於有一個共同祖先進程的各個進程之間。FIFO表明先進先出,單它是一個單向數據流,也就是半雙工,和
管道不一樣的是:每一個FIFO都有一個路徑與之關聯,從而容許無親緣關係的進程訪問。
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
這裏pathname是路徑名,mode是sys/stat.h裏面定義的建立文件的權限.
如下示例程序來自:http://blog.chinaunix.net/uid-20498361-id-1940238.html
有親緣關係進程間的fifo的例子
|
從例子上能夠看出使用fifo時須要注意:
*fifo管道是先調用mkfifo建立,而後再用open打開獲得fd來使用.
*在打開fifo時要注意,它是半雙工的的,通常不能使用O_RDWR打開,而只能用只讀或只寫打開.
fifo能夠用在非親緣關係的進程間,而它的真正用途是在服務器和客戶端之間. 因爲它是半雙工的因此,若是要進行客戶端和服務器雙方的通訊的話,
每一個方向都必須創建兩個管道,一個用於讀,一個用於寫.
下面是一個服務器,對多個客戶端的fifo的例子:
server 端的例子:
|
客戶端的例子:
|