linux程式設計之pipe()函式
管道是一種把兩個程式之間的標準輸入和標準輸出連線起來的機制,從而提供一種讓多個程式間通訊的方法,當程式建立管道時,每次
都需要提供兩個檔案描述符來操作管道。其中一個對管道進行寫操作,另一個對管道進行讀操作。對管道的讀寫與一般的IO系統函式一
致,使用write()函式寫入資料,使用read()讀出資料。
#include<unistd.h>
int pipe(int filedes[2]);
返回值:成功,返回0,否則返回-1。引數陣列包含pipe使用的兩個檔案的描述符。fd[0]:讀管道,fd[1]:寫管道。
必須在fork()中呼叫pipe(),否則子程式不會繼承檔案描述符。兩個程式不共享祖先程式,就不能使用pipe。但是可以使用命名管道。
當管道進行寫入操作的時候,如果寫入的資料小於128K則是非原子的,如果大於128K位元組,緩衝區的資料將被連續地寫入
管道,直到全部資料寫完為止,如果沒有程式讀取資料,則將一直阻塞,如下:
在上例程式中,子程式一次性寫入128K資料,當父程式將全部資料讀取完畢的時候,子程式的write()函式才結束阻塞並且
返回寫入資訊。
命名管道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 端的例子:
|
客戶端的例子:
/*
* Fifo client
*
*/
#include "all.h"
int
main(void)
{
int fdr, fdw;
pid_t pid;
char clt_path[PATH_LEN] = {'\0'};
char buf[MAX_LINE] = {'\0'};
char buf_path[MAX_LINE] = {'\0'};
snprintf(clt_path, PATH_LEN, FIFO_CLT_FMT, (long)getpid());
DBG("clt_path1 = ", clt_path);
snprintf(buf_path, PATH_LEN, "%s\r\n", clt_path);
if (mkfifo(clt_path, FILE_MODE) == -1 && errno != EEXIST)
perr_exit("mkfifo()");
/* client open clt_path for read
* open server for write
*/
if ((fdw = open(FIFO_SVR, O_WRONLY)) < 0)
perr_exit("open()");
/* write my fifo path to server */
if (write(fdw, buf_path, PATH_LEN) != PATH_LEN)
perr_exit("write()");
if (write(fdw, WORDS, WORDS_LEN) < 0) /* write words to fifo server */
perr_exit("error");
if ((fdr = open(clt_path, O_RDONLY)) < 0)
perr_exit("open()");
if (read(fdr, buf, WORDS_LEN) > 0) { /* read reply from fifo server */
buf[WORDS_LEN] = '\0';
printf("server said : %s\n", buf);
}
close(fdr);
unlink(clt_path);
exit(0);
}
相關文章
- Linux系統程式設計之程式替換:exec 函式族Linux程式設計函式
- 【Linux網路程式設計】Socket Api函式Linux程式設計API函式
- 函數語言程式設計入門實踐 —— Compose/Pipe函數程式設計
- linux環境程式設計(2): 使用pipe完成程式間通訊Linux程式設計
- 函式程式設計函式程式設計
- JavaScript中的compose函式和pipe函式JavaScript函式
- JavaScript函數語言程式設計之pointfree與宣告式程式設計JavaScript函數程式設計
- 好程式設計師Python培訓分享函數語言程式設計之匿名函式程式設計師Python函數函式
- python程式設計之slice與indices函式用法Python程式設計函式
- Pandas - pandas.Series.pipe 函式函式
- linux非阻塞式socket程式設計之select()用法Linux程式設計
- 03 shell程式設計之case語句與函式程式設計函式
- JavaScript函數語言程式設計,真香之組合函式(二)JavaScript函數程式設計函式
- JavaScript函數語言程式設計之深入理解純函式JavaScript函數程式設計函式
- select函式socket程式設計函式程式設計
- JS 命令式 宣告式 函式式 程式設計?JS函式程式設計
- Linux之shell程式設計Linux程式設計
- linux之__setup函式Linux函式
- python函數語言程式設計之yield表示式形式Python函數程式設計
- 如何在 Linux Shell 程式設計中定義和使用函式Linux程式設計函式
- 函數語言程式設計-鏈式程式設計RAC函數程式設計
- 不用任何賦值的程式設計稱為*函式式*程式設計賦值程式設計函式
- 揚帆起航:從指令式程式設計到函式響應式程式設計程式設計函式
- Bash程式設計007——函式(一)程式設計函式
- 函式響應式程式設計與RxSwift函式程式設計Swift
- python函式程式設計 返回函式 匿名函式 裝飾器 偏函式Python函式程式設計
- 06_SHELL程式設計之CASE語句+函式+正則程式設計函式
- Linux程式設計之gdb(二)Linux程式設計
- 研究linux函式 之 fork()Linux函式
- 瞭解 JavaScript 函數語言程式設計 - 宣告式函式JavaScript函數程式設計函式
- linux系統時間程式設計(9) 計算程式片段執行時間clock函式Linux程式設計函式
- Ardunio和HAL庫函式程式設計函式程式設計
- 函式設計函式
- linux程式間通訊--管道(PIPE & FIFO)Linux
- Python 函數語言程式設計 – 高階函式Python函數程式設計函式
- Python函數語言程式設計自帶函式Python函數程式設計函式
- Golang物件導向程式設計之建構函式【struct&new】Golang物件程式設計函式Struct
- Day 14 匿名函式 內建函式 物件導向程式設計函式物件程式設計
- Python函數語言程式設計-高階函式、匿名函式、裝飾器、偏函式Python函數程式設計函式