Linux進程間通信——01管道

進程間通信:

對於每個進程來說,都有一份屬於它自己的內存資源,並且獨佔這份內存資源。而進程間通信的目的就是讓不同的進程間能看到一份公共的資源。所有交換的數據必須通過內核來傳遞,在內核中開闢一塊緩衝區,通過這塊緩衝區來實現數據的傳遞,內核提供的這種機制稱爲進程間通信。

進程間通信的方法:1、管道  2、信號量  3、消息隊列  4、共享內存  5、套接字(只有套接字可以跨主機)


匿名管道:pipe(父子間進程的通信方式)

  • 頭文件:#include <unsitd.h>                                                                       
  • 函數:int pipe(int fd[2]);
  • 參數:fd:文件描述符數組,其中fd[0]指向讀端,fd[1]指向寫端。可以通過read(fd[0])或write(fd[1])操作。
  • 返回值:成功返回0,失敗返回-1。
  • 意義:調用這個函數,會在內核中開闢出一塊緩衝區來進行進程間的通信,這塊緩衝區稱之爲管道,有一個讀端和一個寫端。

具體步驟:
                   1、父進程創建管道

                   2、fork創建子進程,子進程也會得到這兩個文件描述符,指向同一管道                                                                      

                   3、父進程關閉讀端(fd[0]),子進程關閉寫端(fd[1])。這樣父進程就可以往管道寫入,子進程可以從子進程讀取。

當進程結束,管道也會自動消失。

代碼實現:

有名管道:fifo

  • 函數:int mkfifo(const char *filename,mode_t mode);//在程序裏創建調用函數
  • 命令:mkfifo fifo(管道名)//在命令行直接創建
  • 參數:文件名和權限
  • 特點:不管是否寫入數據,大小均爲0,直接在內存中寫入。沒有數據會阻塞。

大體思路與匿名管道一致。這裏只展示代碼。

 

總結:

  • 管道是半雙工方式(一個讀,一個寫),但管道分不清內容是誰寫的,所以一般固定傳遞方向。

  • 管道爲空,read阻塞    管道滿,write阻塞。

  • 進程退出,管道釋放,管道的生命週期隨進程。

  • 管道的實現依賴於文件系統。管道是內存上的特殊文件。

  • 管道的大小一般系統將其限制在最大長度爲4096字節的小型文件。

區分:

  1. 無名管道pipe()只能在父子進程中使用;有名管道可以在任意兩個進程中使用

  2. 無名管道:

    1、如果寫端關閉,讀端read返回0

    2、如果讀端關閉,寫異常,發送信號(write -> SIGPIPE),系統默認關閉寫端。

  3. 無名管道:優點:簡單方便;缺點:1)侷限於單向通信2)只能創建在它的進程以及其有親緣關係的進程之間;3)緩衝
    區有限;
    有名管道:優點:可以實現任意關係的進程間的通信;缺點:1)長期存於系統中,使用不當容易出錯;2)緩衝區有限

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章