這塊怎麼說呢 ,就是不怎麼使用,因爲當信息量大的時候,會產生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 +字符 一下就找到了