Java進(jìn)程間通信之消息隊(duì)列
消息隊(duì)列
1.消息隊(duì)列的原理
- 1.1 msgqueue采用鏈表來(lái)實(shí)現(xiàn)消息隊(duì)列, 該鏈表是由系統(tǒng)內(nèi)核維護(hù),
- 1.2 系統(tǒng)中可能有很多的msgqueue, 每個(gè)MQ用消息隊(duì)列描述符(消息隊(duì)列ID: qid) 來(lái)區(qū)分,qid是唯一 的,用來(lái)區(qū)分不同的MQ。
- 1.3在進(jìn)行進(jìn)程間通信時(shí),一個(gè)進(jìn)程將消息加到MQ尾端,另一個(gè)進(jìn)程從消息隊(duì)列中取消息(不一 定以先進(jìn)先出來(lái)取消息,也可以按照消息類(lèi)型去取消息)這樣就實(shí)現(xiàn)了進(jìn)程間的通信。
2.消息隊(duì)列的接口:
2.1創(chuàng)建消息隊(duì)列
int msgget(key_ t key, int msgflg);
參數(shù):
key
:消息隊(duì)列的標(biāo)識(shí)符msgflg
:創(chuàng)建的標(biāo)志,例如IPC_CREATIPC_CREAT
:如果不存在就創(chuàng)建:按位或上一個(gè)權(quán)限(8進(jìn)制的數(shù)字)
返回值:
- 成功:返回隊(duì)列ID
- 失敗:返回-1,并設(shè)置erron
2.2向消息隊(duì)列發(fā)送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
參數(shù):
msgid
:消息隊(duì)列IDmsgp
:指向msgbuf 的指針,用來(lái)指定發(fā)送的消息- 操作系統(tǒng)為該函數(shù)發(fā)送的消息定義了發(fā)送格式,只是定義了一部分,另一部分要程序員自己去定義
msgsz
:要發(fā)送消息的長(zhǎng)度,消息內(nèi)容的長(zhǎng)度msgflg
:創(chuàng)建標(biāo)記,如果指定IPC_NOWAIT,失敗會(huì)立即返回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
:消息隊(duì)列IDmsgp
:指向msgbuf的指針,用來(lái)接收消息msgsz
:要接收消息的長(zhǎng)度- 注意:參數(shù)msgsz 指定由msgp 參數(shù)指向的結(jié)構(gòu)的成員mtext的最大大小(以字節(jié)為單位)
msgtyp:接收消息的方式
- 1.
msgtyp = 0
:讀取隊(duì)列中的第一條消息(不在乎當(dāng)前對(duì)頭元素時(shí)什么消息類(lèi)型,將他當(dāng)作普通隊(duì)列來(lái)處理) - 2.
msgtyp > 0
:讀取隊(duì)列中類(lèi)型為msgtyp 的第一條消息。(就是讀取對(duì)列元素中第一個(gè)香蕉)除非在msgflg中指定了MSG_ EXCEPT, 將讀取類(lèi)型不等于msgtyp 絕對(duì)值的第一條消息 - 3.
msgtyp< : 0
:讀取隊(duì)列中最小類(lèi)型小于或等于msgtyp 絕對(duì)值的第一條消息
msgflg
:創(chuàng)建標(biāo)記,如果指定IPC_ NOWAIT,獲取失敗會(huì)立刻返回
返回值:
- 成功返回實(shí)際讀取消息的字節(jié)數(shù)
- 失敗返回-1,并設(shè)置erron
2.4操作消息隊(duì)列的接口
int msgctl(int msqid, int cmd, struct msqid_ ds *buf);
參數(shù):
msqid
:消息隊(duì)列IDcmd
:控制命令,- 例如
IPC_ RMID
,刪除命令 , IPC STAT
,獲取狀態(tài)
- 例如
- buf:存儲(chǔ)消息隊(duì)列的相關(guān)信息的buf
返回值:
- 成功根據(jù)不同的cmd有不同的返回值,
- 失敗返回-1,并設(shè)置erron
2.5代碼測(cè)試:
創(chuàng)建一個(gè)消息對(duì)列,寫(xiě)端發(fā)送消息對(duì)列,讀端讀取消息對(duì)列中的內(nèi)容。
我們運(yùn)行寫(xiě)端代碼兩次發(fā)現(xiàn)消息對(duì)列中寫(xiě)入20條消息,
運(yùn)行讀端代碼我們發(fā)現(xiàn)成功讀出
我們運(yùn)行三次可以發(fā)現(xiàn)再無(wú)法從消息對(duì)列中讀出,說(shuō)明消息對(duì)列每次獲取到消息后,就會(huì)將消息對(duì)列中相應(yīng)的消息出對(duì)列
信號(hào)量:
信號(hào)量的原理
- 信號(hào)量本質(zhì)上就是資源計(jì)數(shù)器,能夠保證多個(gè)進(jìn)程之間訪問(wèn)臨界資源,執(zhí)行臨 界區(qū)代碼時(shí),互斥訪問(wèn)。同時(shí)也可以用于同步
- 臨界資源:多個(gè)進(jìn)程都可以訪問(wèn)到的資源(例如:同一塊內(nèi)存)
- 臨界區(qū):訪問(wèn)臨界資源時(shí)的代碼,區(qū)域稱(chēng)之為臨界區(qū)
互斥訪問(wèn):同一時(shí)刻,多個(gè)進(jìn)程當(dāng)中,只有一個(gè)進(jìn)程可以訪問(wèn)臨界區(qū)資源。多個(gè)資源通過(guò)信號(hào)量保證互斥訪問(wèn)的時(shí)候,需要先獲取信號(hào)量,如果能獲取正確的信息量,則才能訪問(wèn)臨界資源,如果獲取不了,則阻塞等待。等待訪問(wèn)的進(jìn)程將信號(hào)量設(shè)置為1,然后再訪問(wèn)。
- 如果不進(jìn)行互斥訪問(wèn)會(huì)造成結(jié)果二義性。(結(jié)果不同)(多核cpu同時(shí)運(yùn)行多個(gè)進(jìn)程訪問(wèn)臨界資源,單核搶占式執(zhí)行,操作系統(tǒng)調(diào)度不可控)
- 同步:當(dāng)臨界資源空閑之后,通知等待的進(jìn)程進(jìn)行訪問(wèn)
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
- Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過(guò)程源代碼分析
- Java獲取Process子進(jìn)程進(jìn)程ID方法詳解
- Java進(jìn)程內(nèi)緩存框架EhCache詳解
- Java 動(dòng)態(tài)模擬操作系統(tǒng)進(jìn)程調(diào)度算法
- Arthas在線(xiàn)java進(jìn)程診斷工具在線(xiàn)調(diào)試神器詳解
- Java進(jìn)程cpu頻繁100%問(wèn)題解決方案
- Java進(jìn)程cpu占用過(guò)高問(wèn)題解決
- SystemServer進(jìn)程啟動(dòng)過(guò)程解析
相關(guān)文章
Minio與SpringBoot使用okhttp3問(wèn)題解決
這篇文章主要介紹了Minio與SpringBoot使用okhttp3問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10SpringBoot?ScheduledTaskRegistrar解決動(dòng)態(tài)定時(shí)任務(wù)思路詳解
本文將從問(wèn)題出發(fā),詳細(xì)介紹ScheduledTaskRegistrar類(lèi)是如何解決動(dòng)態(tài)調(diào)整定時(shí)任務(wù)的思路,并給出關(guān)鍵的代碼示例,幫助大家快速地上手學(xué)習(xí)2023-02-02Jetty啟動(dòng)項(xiàng)目中引用json-lib相關(guān)類(lèi)庫(kù)報(bào)錯(cuò)ClassNotFound的解決方案
今天小編就為大家分享一篇關(guān)于Jetty啟動(dòng)項(xiàng)目中引用json-lib相關(guān)類(lèi)庫(kù)報(bào)錯(cuò)ClassNotFound的解決方案,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12JAVA實(shí)現(xiàn)按時(shí)間段查詢(xún)數(shù)據(jù)操作
這篇文章主要介紹了JAVA實(shí)現(xiàn)按時(shí)間段查詢(xún)數(shù)據(jù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08