首先理解管道其實是乙個二進位制位元組流,它是核心為維持兩個或多個程序互相通訊的一種手段(一種ipc)。如下圖所示:
#include#include #include #include #include #define buf_siz 10
int main(int argc,char *argv)
write(1,"\n",1);
close(field[0]);
default:
close(field[0]);
write(field[1],argv[1],strlen(argv[1]));
close(field[1]);
wait(null);
exit(0);
}}
此時我將每次讀取的內容設定為10個位元組,一次寫入管道中的位元組超過10個時,可以在終端看到,10個位元組後,一部分內容是在延遲3s才在終端顯示的。
值得一提的是,當讀取管道時,如果管道中沒有資料,那麼read會阻塞,直到管道中有新的位元組流。如果管道的寫入端關閉了,那麼在read完管道中剩下的位元組流之後,將會看到檔案結尾(read會返回0),當write進管道時,一次寫入太大的位元組流(其實管道可以看做乙個核心快取,快取的大小是固定的,不同的系統大小不一樣,linux是465536),管道容納不了一次寫這麼多,那麼write也會阻塞。
建立和使用管道:
int pipe(int field[2])
即可建立管道,其中field[0]是管道讀取端,field[1]是管道寫入端。一般在乙個程序中建立管道也沒有什麼意義。一般管道是用於父程序與其子程序之類的進行通訊。
儘管管道支援多個程序寫入和讀取,但是一般不那麼做。一般設定為父程序寫入,子程序讀取或者子程序寫入,父程序讀取,使得它們之間開始通訊。
注意在建立管道過程中,及時關閉不使用的檔案描述符是很有必要的。
從管道中讀取資料的程序(如上圖b中所示的子程序)應該關閉其寫入端的檔案描述符(圖44-3 b)中子程序的field[1].因為如果在別的程序都已經寫入資料完成,並且已經關閉了寫入檔案描述符,按照原本的思想,該次通訊已經完成,此時已經沒有資料從父程序傳給子程序了。但是由於子程序的寫入管道端檔案描述符未關閉,讓子程序讀取端誤認為至少還有乙個程序沒有完成寫入,那麼子程序的讀取端會一直阻塞地read下去。而寫入端關閉讀取檔案操作符是處於不同的原因。當乙個程序試圖向管道中寫入資料但沒有任何程序擁有該管道開啟的讀描述符,核心會向寫入程序傳送乙個sigpipe訊號。預設下,該訊號會殺死乙個程序。當然,程序也可以捕捉或者忽略該訊號。收到sigpipe訊號對於表示管道的狀態很有用。
關閉未使用檔案描述符的最後乙個原因是當所有程序的所有引用乙個管道的檔案描述符被關閉後,才會銷毀該管道,釋放管道資源。
還有另外一種管道,它叫fifo管道,但是它在檔案系統中有乙個名稱,開啟它和開啟乙個普通檔案是一樣的。不同的是管道只能用於有「血緣」關係的程序間通訊,fifo可以對在任意程序之間通訊(如客戶端和伺服器)。
文章參考linux/unix系統程式設計手冊一書。
linux系統學習之Umask
linux系統學習之umask。檔案許可權管理之 umask mask 新建檔案 目錄的預設許可權是由mask決定的 umask 會影響到mask,umask表示要減掉的許可權 shell vim,touch umask 新檔案或目錄許可權 vsftpd umask 新檔案或目錄許可權 samba ...
Linux系統學習之興趣驅動
學習原本應該是一件快樂的事情,孔子雲 學而時習之,不亦說乎?學習能夠增長人的知識 見聞,讓人歡心,使人受益。但是令人遺憾的是,當前我們所處的環境,不敢說全部,至少大部分學習的人,應該是感受不到學習的樂趣。面對學不完的知識 做不完的題,面對家長殷切的期盼 老師嚴厲的目光,還有對未來的迷茫與不安,整天除...
Linux系統學習之興趣驅動
學習原本應該是一件快樂的事情,孔子雲 學而時習之,不亦說乎?學習能夠增長人的知識 見聞,讓人歡心,使人受益。但是令人遺憾的是,當前我們所處的環境,不敢說全部,至少大部分學習的人,應該是感受不到學習的樂趣。面對學不完的知識 做不完的題,面對家長殷切的期盼 老師嚴厲的目光,還有對未來的迷茫與不安,整天除...