對於一些須要進程間的協做來解決問題的場景,進程間的通訊是必要的。而最簡單的UNIX進程通訊機制就是管道,他是由特殊文件表示的。調用者能夠經過文件描述符fd[0]和fd[1]來訪問它,從fd[1]寫入的數據能夠按照先進先出的順序從fd[0]中讀出。html
文件描述符:在形式上是一個非負整數。實際上,它是一個索引值,指向內核爲每個進程所維護的該進程打開文件的記錄表。當程序打開一個現有文件或者建立一個新文件時,內核向進程返回一個文件描述符。在程序設計中,一些涉及底層的程序編寫每每會圍繞着文件描述符展開。可是文件描述符這一律念每每只適用於UNIX、Linux這樣的操做系統。shell
咱們要明白,每一個Unix進程(除了可能的守護進程)應均有三個標準的POSIX文件描述符,對應於三個標準流:vim
整數值 | 名稱 | <unistd.h>符號常量 | <stdio.h>文件流 |
---|---|---|---|
0 | Standard input | STDIN_FILENO | stdin |
1 | Standard output | STDOUT_FILENO | stdout |
2 | Standard error | STDERR_FILENO | stderr |
例如:$ls -l | head -5
中,|
就表示一個管道,ls
的標準輸出被經過中間通訊緩衝區被「鏈接」到了head
的標準輸入中。 函數
瞭解了文件描述符的概念後,咱們就能利用dup2
函數來實現重定向。下面咱們來用c語言模擬$ls -l | head -5
。spa
#include <errno.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main(int argc, char *argv[]) { pid_t child; int fd[2]; if ((pipe(fd) == -1) || ((child = fork()) == -1)) { perror("Failed to fork."); return 1; } if (child == 0) { /* 子進程 */ if (dup2(fd[1], STDOUT_FILENO) == -1) perror("Failed to redirect stdout of ls"); else if ((close(fd[0]) == -1) || (close(fd[1]) == -1)) perror("Failed to close extra pipe descriptors on ls"); else { execl("/bin/ls", "ls", "-l", NULL); perror("Failed to execute ls"); } } /* 父進程 */ if (dup2(fd[0], STDIN_FILENO) == -1) perror("Failed to redirect stdin of head"); else if ((close(fd[0]) == -1) || (close(fd[1]) == -1)) perror("Failed to close extra pipe descriptors on head"); else { execl("/usr/bin/head", "head", "-5", NULL); perror("Failed to execute head"); } return 0; }
fork
函數在建立一個子進程時,子進程就會繼承父進程的環境和上下文中的大部份內容的一份拷貝,包括信號狀態
,調度參數
和文件描述符表
。因爲子進程在被建立時會收到父進程文件描述符表的一份拷貝,所以對於在建立子進程前就打開的文件來書,父進程和子進程將共享同一個文件的偏移量。 調用fork
後,文件描述符表狀態以下: 操作系統
兩個dup2
函數執行完畢後,文件描述符表的狀態以下: 設計
調用close
完畢後,文件描述符表的狀態以下: 3d
$ gcc redirect_demo.c $ ./a.out total 4888 -rwxrwxr-x 1 chris chris 8576 3月 5 21:23 a.out drwxrwx--- 10 chris chris 4096 3月 5 21:23 ccls -rw-rw-r-- 1 chris chris 637 3月 5 21:23 coc-25627.vim -rw-rw-r-- 1 chris chris 25829 3月 5 15:06 coc-ultisnips-c7dd5acb3d1574c377e86b60ee637c3c.py
原文出處:https://www.cnblogs.com/chrisynl/p/12422837.htmlcode