進程通訊(一)--有名管道

  進程間通訊的意義很多書上都有說,總之是非常重要的一部分,就不多囉嗦了,簡單來說是爲了完成進程間的協作功能。
  然而進程間的通訊方式也不少,信號,信號量,管道,共享內存.....
  今天先來說說管道中的有名管道。當然有有名管道自然也有無名管道。至於他倆的區別,我們暫且記着有名管道是可以讓同一臺計算機上的任意兩個無關係的進程通信。而無名管道則是必須需要通信的進程間存在關係,比如父子進程。
  有名管道的原理是什麼呢?有名管道的管道具體在計算機的哪個地方呢?
  請看下面這張示意圖
   
有名管道是在進程使用管道時在系統內存上開闢的一段空間,如果A需要給B傳遞某些信息,A進程就給那段開闢的空間裏寫入數據,而B也從那段開闢的空間裏讀取數據,並且重要的一點是管道保存的數據是未被進程讀的,或者說B讀數據就好比循環隊列,讀過的數據就出隊消毀了,不會停留在管道中被重複讀取,就好比接電話,音過了就過了,不會爲你保存一份錄音 供你重複聽。
既然是內存上開闢的空間。那就說明管道不會佔用磁盤的空間。
管道文件好比是一個標記。供使用這個標記的進程們在運行時 使用同一段指定的內存 進行通訊,讀寫數據。

創建管道有兩種形式
是在命令窗口使用mkfifo 管道名 
是代碼中調用系統函數mkfifio();
之後的操作就把管道看作文件,使用文件操作就好
   打開: open  寫數據:write 讀數據:read  關閉:close
值得注意的是對管道的一些文件操作函數會阻塞運行
何爲阻塞運行?就是函數調用以後並不會立即返回,需要等待某些條件的發生纔會返回。
如果一個進程以只寫方式打開一個管道文件,open就會阻塞運行,直到一個進程以讀方式打開文件該管道文件,open纔會返回,進程纔會繼續執行。
這樣設計的目的何在?我們都知道管道是爲了傳輸數據,如果沒有要傳給的對象,也就是沒有其他進程讀取管道內容,那麼給管道標記的那段內存寫數據將沒有意義,浪費內存空間,而且我們之前也說了管道的那段內存是循環隊列,只有讀數據纔會把內存的數據出隊,沒進程使數據出隊,一個勁兒的寫,勢必也是不好的。當然的,一般不會出現管道寫入數據把內存擠爆的情況,因爲管道是有默認大小的。
  read也會阻塞運行。如果其他進程沒有給管道寫入數據 或者 寫入數據的進程全部關閉了。read當然沒有讀的意義了,就會阻塞運行。
  write雖然也會阻塞運行,但阻塞條件比較難達成,就是管道寫滿的情況。
  之前也說了管道是有大小的,會寫滿,那麼它究竟有多大呢?
  寫個簡單的代碼測試一下


寫了65536個a後就阻塞住了,65536個字節=2^16 byte=2^6 kb=64k
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章