Java進程間通信之消息隊列
消息隊列
1.消息隊列的原理
- 1.1 msgqueue采用鏈表來實現(xiàn)消息隊列, 該鏈表是由系統(tǒng)內(nèi)核維護,
- 1.2 系統(tǒng)中可能有很多的msgqueue, 每個MQ用消息隊列描述符(消息隊列ID: qid) 來區(qū)分,qid是唯一 的,用來區(qū)分不同的MQ。
- 1.3在進行進程間通信時,一個進程將消息加到MQ尾端,另一個進程從消息隊列中取消息(不一 定以先進先出來取消息,也可以按照消息類型去取消息)這樣就實現(xiàn)了進程間的通信。

2.消息隊列的接口:
2.1創(chuàng)建消息隊列
int msgget(key_ t key, int msgflg);

參數(shù):
key:消息隊列的標識符msgflg:創(chuàng)建的標志,例如IPC_CREATIPC_CREAT:如果不存在就創(chuàng)建:按位或上一個權(quán)限(8進制的數(shù)字)
返回值:
- 成功:返回隊列ID
- 失敗:返回-1,并設(shè)置erron
2.2向消息隊列發(fā)送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
參數(shù):
msgid:消息隊列IDmsgp:指向msgbuf 的指針,用來指定發(fā)送的消息- 操作系統(tǒng)為該函數(shù)發(fā)送的消息定義了發(fā)送格式,只是定義了一部分,另一部分要程序員自己去定義

msgsz:要發(fā)送消息的長度,消息內(nèi)容的長度msgflg:創(chuàng)建標記,如果指定IPC_NOWAIT,失敗會立即返回0:阻塞發(fā)送IPC_NOWAIT:非阻塞發(fā)送
返回值:
- 成功:返回0
- 失敗:返回-1,并設(shè)置erron
2.3接收消息:
ssize_t msgrcv(int msqid, void *msgp, sizet msgsz, long msgtyp, int msgflg);

參數(shù):
msgid:消息隊列IDmsgp:指向msgbuf的指針,用來接收消息msgsz:要接收消息的長度- 注意:參數(shù)msgsz 指定由msgp 參數(shù)指向的結(jié)構(gòu)的成員mtext的最大大小(以字節(jié)為單位)
msgtyp:接收消息的方式
- 1.
msgtyp = 0:讀取隊列中的第一條消息(不在乎當前對頭元素時什么消息類型,將他當作普通隊列來處理) - 2.
msgtyp > 0:讀取隊列中類型為msgtyp 的第一條消息。(就是讀取對列元素中第一個香蕉)除非在msgflg中指定了MSG_ EXCEPT, 將讀取類型不等于msgtyp 絕對值的第一條消息 - 3.
msgtyp< : 0:讀取隊列中最小類型小于或等于msgtyp 絕對值的第一條消息
msgflg:創(chuàng)建標記,如果指定IPC_ NOWAIT,獲取失敗會立刻返回
返回值:
- 成功返回實際讀取消息的字節(jié)數(shù)
- 失敗返回-1,并設(shè)置erron
2.4操作消息隊列的接口
int msgctl(int msqid, int cmd, struct msqid_ ds *buf);
參數(shù):
msqid:消息隊列IDcmd:控制命令,- 例如
IPC_ RMID,刪除命令 , IPC STAT,獲取狀態(tài)
- 例如
- buf:存儲消息隊列的相關(guān)信息的buf
返回值:
- 成功根據(jù)不同的cmd有不同的返回值,
- 失敗返回-1,并設(shè)置erron
2.5代碼測試:
創(chuàng)建一個消息對列,寫端發(fā)送消息對列,讀端讀取消息對列中的內(nèi)容。

我們運行寫端代碼兩次發(fā)現(xiàn)消息對列中寫入20條消息,

運行讀端代碼我們發(fā)現(xiàn)成功讀出

我們運行三次可以發(fā)現(xiàn)再無法從消息對列中讀出,說明消息對列每次獲取到消息后,就會將消息對列中相應的消息出對列

信號量:
信號量的原理
- 信號量本質(zhì)上就是資源計數(shù)器,能夠保證多個進程之間訪問臨界資源,執(zhí)行臨 界區(qū)代碼時,互斥訪問。同時也可以用于同步
- 臨界資源:多個進程都可以訪問到的資源(例如:同一塊內(nèi)存)
- 臨界區(qū):訪問臨界資源時的代碼,區(qū)域稱之為臨界區(qū)

互斥訪問:同一時刻,多個進程當中,只有一個進程可以訪問臨界區(qū)資源。多個資源通過信號量保證互斥訪問的時候,需要先獲取信號量,如果能獲取正確的信息量,則才能訪問臨界資源,如果獲取不了,則阻塞等待。等待訪問的進程將信號量設(shè)置為1,然后再訪問。

- 如果不進行互斥訪問會造成結(jié)果二義性。(結(jié)果不同)(多核cpu同時運行多個進程訪問臨界資源,單核搶占式執(zhí)行,操作系統(tǒng)調(diào)度不可控)
- 同步:當臨界資源空閑之后,通知等待的進程進行訪問

總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
SpringBoot?ScheduledTaskRegistrar解決動態(tài)定時任務思路詳解
本文將從問題出發(fā),詳細介紹ScheduledTaskRegistrar類是如何解決動態(tài)調(diào)整定時任務的思路,并給出關(guān)鍵的代碼示例,幫助大家快速地上手學習2023-02-02
Jetty啟動項目中引用json-lib相關(guān)類庫報錯ClassNotFound的解決方案
今天小編就為大家分享一篇關(guān)于Jetty啟動項目中引用json-lib相關(guān)類庫報錯ClassNotFound的解決方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12
JAVA實現(xiàn)按時間段查詢數(shù)據(jù)操作
這篇文章主要介紹了JAVA實現(xiàn)按時間段查詢數(shù)據(jù)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08

