消息隊列
消息隊列的結構有很多,但在這裏講的隊列的結構都是基於鏈表實現的.
進程間通信的實質是:讓不同的進程可以看到相同的資源. |
消息隊列的特點:
- 消息隊列的通信是通過發送有類型數據塊的方法.
- 每個數據塊都有一個類型,接收方接受的數據塊可以有不同的類型值.
- 消息隊列的最大長度有限制.(缺點,因爲消息隊列必定要佔用內存,而如果只發送不接受就會耗內存.)
所以:消息隊列提供了一個進程向另一個進程發送了有類型數據塊的方法.
實現消息隊列的相關函數:
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
函數作用:爲創建消息隊列的函數提供參數.
注意:對於這個函數,若函數的參數相同,則函數的返回值相同.
①創建消息隊列的函數:
int msgget(key_t key,int msgflg);
msgflg:與文件的權限mode是相同的.
常用的參數有:
IPC_CREAT:不存在就創建,若存在就打開.
IPC_EXCL:若存在,就失敗.與上面的搭配使用.
函數創建成功就返回非負整數
②消息隊列控制函數
int magctl(int msqid,int cmd,struct msqid_ds *buf);
參數:
msqid_ds:表示消息隊列
cmd:函數執行的作用:IPC_RMID(刪除消息隊列)
函數返回值:成功返回0失敗返-1;
③把消息添加到消息隊列中
int msgsnd(int msqid,const void* msgp,size_t msgsz,int msqflg);
④從一個消息隊列中接收消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
msgp:指向接受的消息的隊列.
msgsz:消息隊列的長度.
msgtyp:可以實現接收優先級.若爲0,就是普通的隊列.
查看消息隊列的指令:ipcs -q 手動刪除某個消息隊列:ipcrm -q 進程id |
總結消息隊列: 1. 全雙工的通信方式. 2. 面向數據塊. 3. 內置同步互斥機制. 4. 聲明週期隨內核.(可以通過手動刪除和重啓來刪除一個消息隊列). 5. 可以用於任意進程. |
共享內存
每個進程都有自己的虛擬內存空間,而物理空間只有一份,當多個進程映射到相同的物理地址後,那麼就可以共同訪問這塊內存.即共享內存.
蹦蹦蹦:共享內存是最快的進程間通信的方式(省略了兩次內存拷貝).但是同時也是不穩定的,由於共同訪問同一塊內存,會產生不可預知的錯誤.
實現共享內存調用的相關函數:
int shmget(key_t key,size_t size,int shmget);
key:共享內存段的名字.
size:共享內存的大小.(按頁的大小向上取整.一般而言頁的大小爲4K)
shmflg:與消息隊列的那個參數相同.
void* shmat(int shmid,const void* shmaddr,int shmflg);
shmaddr:共享內存連接的地址.
成功返回一個指向共享內存的第一個指針,失敗返回-1.
int shmctl(int shmid,int cmd,struct_ds *buf);
cmd:與消息隊列中的那個參數相同.
buf:指向一個保存着共享內存的模式狀態和訪問權限的數據結構.
總結共享內存: 1. 雙向通信全雙工. 2. 用於任意進程間的通信方式. 3. 不存在”面向數據報”和”面向字節流”. 4. 沒有同步互斥機制. 5. 生命週期隨內核. |
信號量
爲什麼要有信號量的通信方式? 消息隊列,共享內存以及管道都是可以同時又多個進程去訪問公共資源,可能會引發一系列的問題.而信號量是爲了通過控制其他的通信的公共資源來實現進程間通信.信號量則會負責數據操作的同步,互斥等. |
信號量的同步指的是所有的進程按照一定的順序去執行任務,實現對資源的有序訪問.
信號量的互斥指的是當有一個進程在臨界區時,其餘的進程只能等待,等待那個進程出了臨界區.
信號量的PV操作
這裏的信號量指的是二元信號量,非0即1.
P操作:申請使用臨界資源,信號量減一;
V操作:釋放臨界資源,信號量加一.
注意:消息隊列,共享內存以及信號量都是基於system V版本的進程間通信的方式.