[TOC] 1. 管道(無名管道) pipe函數 管道由pipe函數創建,提供一個單向半雙工數據流,它沒有名字,只能在父子進程間使用。 pipe通過參數fd[2]返回兩個文件描述符:fd[0]用於讀,fd[1]用於寫,管道的典型的用法如下: 父進程創建一個管道,然後調用fork創建子進程 父進程關閉 ...
目錄
1. 管道(無名管道)
pipe函數
管道由pipe函數創建,提供一個單向半雙工數據流,它沒有名字,只能在父子進程間使用。
#include <unistd.h>
//成功返回0,失敗返回-1
int pipe(int fd[2]);
pipe通過參數fd[2]返回兩個文件描述符:fd[0]用於讀,fd[1]用於寫,管道的典型的用法如下:
- 父進程創建一個管道,然後調用fork創建子進程
- 父進程關閉fd[0],即父進程只負責寫
- 子進程關閉fd[1],即子進程只負責讀
這樣,就實現了一個從父進程——>子進程的單向數據通道,如下圖所示。
當然,上述用法還可以再進一步,父進程fork前再創建一個管道,按相同的方法實現一個從子進程——>父進程的單向數據通道。
兩個管道結合,就實現了父子進程之間的雙向數據通道,如下圖所示。
popen函數
作為一個關於管道的例子,標準IO庫提供了popen函數,它創建一個管道並啟動另外一個進程,該進程要麼通過該管道從標準輸入讀,要麼通過該管道向標準輸出寫。
#include <stdio.h>
//成功返迴文件指針,失敗返回NULL
FILE *popen(const char *command, const char *type);
//成功返回shell終止狀態,失敗返回-1
int pclose(FILE *fp);
其中command必須是一個shell命令行,由popen返回的FILE指針fp,要麼用於輸入,要麼用於輸出,取決於type的值:
- 如果type為"r",那麼調用進程通過fp可以獲取popen的輸出
- 如果type為"w",那麼調用進程通過fp可以向popen寫,寫入的內容作為popen的輸入
pclose關閉由popen創建的標準IO流。
2.FIFO(有名管道)
FIFO也是一個單向半雙工數據流,但每個FIFO都有一個路徑名與之關聯,因此可以用於無親緣關係的進程之間,FIFO也稱為有名管道。
- mkfifo用於創建一個FIFO,該函數內部隱含指定 O_CREAT | O_EXCL
- 打開一個已存在的FIFO,應該使用open,且只能以只讀或只寫方式打開
#include <sys/types.h>
#include <sys/stat.h>
//成功返回0,失敗返回-1
int mkfifo(const char *pathname, mode_t mode);
pathname是用於標識FIFO的路徑名,mode含義與可設的值同Posix IPC創建函數,即6個S_IRXXX常值,具體細節在Posix信號量一文中有講過。