進程間通信

這塊怎麼說呢 ,就是不怎麼使用,因爲當信息量大的時候,會產生BUG
,但是他還是有點用的,

最重要 且最牛逼 但也比較難 的進程通信爲
:網絡

爲什麼要進程通信?
因爲 進程具有獨立性(每個進程都有自己的虛擬地址空間) ,兩個進程 彼此並不直到對方的狀態
通訊需要介質,兩個進程都能訪問的公共資源:

進程間通信可以 :
1 傳輸數據
2資源共享
3 通知事件
4 進程控制
文件 (共享內存) 消息隊列 信號量

進程間通信的分類:

**1 管道(我們把一個進程連接另一個進程的數據流 稱爲管道)
1 匿名管道 pipe
2 命名管道
2 System V IPC
System V 消息隊列
System V 共享內存
System V 信號量

**3 POSIX IPC
消息隊列
共享內存
信號量
互斥量
條件變量
讀寫鎖

1 管道

~~
管道是內核中維護的 ,類似隊列的一種形式: 單向通行
wc - l 書有多少行
eg ps aux | wc - l
在這裏插入圖片描述

怎麼實現一個管道?

#include“unistd.h”
功能  :  創建無名管道
int pipe(int fd[ 2],mode_t  mode);
參數:  
fd :文件描述符
fd[0]表示讀端
fd[1]表示寫端
mode  權限
成功返回 0  失敗 返回錯誤代碼

也可以在命令行下創建管道
mkfifo + 管道名

因爲管道是內核中維護的,他有一段內存 ,構成了一個隊列,因爲內核中的內存我們不好管理,我們借用fd來進行讀寫操作

下面測試一個簡單的一對讀寫
在這裏插入圖片描述
在這裏插入圖片描述

發現讀寫均成功!

管道中的數據一旦被 read,就相當於出隊列了;
同一份數據,只有一個進程能讀到,因爲管道內部具有“”同步互斥機制“”

同步互斥機制 保證多進程同時讀寫不會出錯 ;也保證空管道時,如果嘗試讀,就在 read處發生阻塞

通信在這裏插入圖片描述

注意 : 管道的大小隻有64 K 即65536 ,-------大小可以通過修改管道的默認屬性,再調用讀,或寫,都可以獲取到。

匿名管道必須用於具有親緣關係的進程之間
管道的親緣關係 ,父子爺孫,即 直系的 ,不含叔伯旁系管道。

管道的讀寫規則

以下內容瞭解一下就行

設置文件描述符的函數

int fcntl(int fd , int cmd ,/*args)
fd: 文件描述符
cmd :命令:
F_GETFL:獲取當前文件描述符屬性
F_SETFL:設置當前文件描述符屬性
返回值 :文件描述符的屬性;通過位圖方式返回。

非阻塞 :O_NONBLOCK

阻塞式 可以通過返回值 安位或O_BLOCK;

通過設置,就可以模擬 修改默認的阻塞式等待,再模擬會發生什麼。(預想,什麼都讀不到 )

阻塞:
屬性: 默認阻塞式

類似於 管道的讀阻塞 ,寫阻塞;

測試

測試 1 不進行讀,只寫。
1 讀端不關閉,一直寫, write 返回 -1 ,報錯資源不可用 。
2 讀端關閉 ,一直寫,造成寫端收到SIGPIPE信號,寫端程序被殺死,同時管道破裂。

測試2 不寫 ,只讀
1 寫端不關閉,一直讀,read 返回-1,同時報錯資源不可用
2 寫端關閉, 一直讀,read 返回正常,同時返回讀到的字節數。

最後管道不能打開O,就像籃球不能打開。打開意味着破裂。

1 同步互斥機制

2 擁塞等待機制

管道的特點:
1 管道提供流式服務

2 一般而言,所有引用管道的進程結束(引用計數),管道釋放

3 一般而言,內核對管道的操作進行同步與互斥(多進程同時讀寫不會錯亂,滿了發生堵塞等待)

4 管道只能用於具有親緣關係的進程之間的通信,** 即 具有共同祖先**

5 管道 半雙工通信(數據單向流動),需要雙向就用兩個管道唄!

6 向管道中讀寫數據 一定要保證原子性。 負責數據會失效。

既然 管道的讀寫是阻塞式的,那麼一個進程含有多個read/write 呢,
假如 需要阻塞等待的文件,來的順序剛好不是理想順序 ,這時 會發生什麼 ?

這時就形成了死鎖。

處理方式 : 集中等待 ,收到哪個,就釋放哪個的阻塞。
select 就採用了 集中監聽的
select函數 ,即IO多路複用技術。

vim 下標籤頁的基本操作

:tabe (tabedit) + filename 打開(創建)標籤頁
gt 切換到下一個標籤頁
gT切換到上一個標籤頁
:q關閉當前標籤頁
:qa 關閉全部標籤頁
:set mousa=a 啓用鼠標
行內找字符 f +字符 一下就找到了

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