Linux--消息隊(duì)列

概述

消息隊(duì)列是消息的鏈表恩沽,存放在內(nèi)存中誊稚,由內(nèi)核維護(hù)消息隊(duì)列的特點(diǎn)。

1罗心、消息隊(duì)列中的消息是有類型的里伯。
2、消息隊(duì)列中的消息是有格式的渤闷。
3疾瓮、消息隊(duì)列可以實(shí)現(xiàn)消息的隨機(jī)查詢。消息不一定要以先進(jìn)先出的次序讀取飒箭,編程時可以
按消息的類型讀取狼电。
4蜒灰、消息隊(duì)列允許一個或多個進(jìn)程向它寫入或者讀取消息。
5肩碟、與無名管道强窖、命名管道一樣,從消息隊(duì)列中讀出消息削祈,消息隊(duì)列中對應(yīng)的數(shù)據(jù)都會被刪除翅溺。
6、每個消息隊(duì)列都有消息隊(duì)列標(biāo)識符髓抑,消息隊(duì)列的標(biāo)識符在整個系統(tǒng)中是唯一的咙崎。
7、只有內(nèi)核重啟或人工刪除消息隊(duì)列時吨拍,該消息隊(duì)列才會被刪除褪猛。若不人工刪除消息隊(duì)列,消息隊(duì)列會一直存在于系統(tǒng)中

在ubuntu 某些版本中消息隊(duì)列限制值如下:
每個消息內(nèi)容最多為8K字節(jié)
每個消息隊(duì)列容量最多為16K字節(jié)
系統(tǒng)中消息隊(duì)列個數(shù)最多為1609個
系統(tǒng)中消息個數(shù)最多為16384個

消息隊(duì)列的API

1密末、獲取系統(tǒng)唯一的key值

#include<sys/types.h>
#include<sys/ipc.h>
key_t ftok(const char *pathname ,int proj_id);

功能:
????????獲得項(xiàng)目相關(guān)的唯一的IPC鍵值。
參數(shù):
????????pathname:路徑名
????????proj_id:項(xiàng)目ID跛璧,非0整數(shù)(只有低8位有效)
返回值:
????????成功返回key值严里,失敗返回 -1

2、創(chuàng)建消息隊(duì)列

#include<sys/msg.h>
int msgget(key_t key,int msgflg);

功能:
????????創(chuàng)建一個新的或打開一個已經(jīng)存在的消息隊(duì)列追城。不同的進(jìn)程調(diào)用此函數(shù)刹碾,只要用相同的key值就
????????能得到同一個消息隊(duì)列的標(biāo)識符。
參數(shù):
????????key:IPC鍵值座柱。
????????msgflg:標(biāo)識函數(shù)的行為及消息隊(duì)列的權(quán)限迷帜。
????????????msgflg的取值:
????????????IPC_CREAT:創(chuàng)建消息隊(duì)列。
????????????PC_EXCL:檢測消息隊(duì)列是否存在色洞。
????????????位或權(quán)限位:消息隊(duì)列位或權(quán)限位后可以設(shè)置消息隊(duì)列的訪問權(quán)限戏锹,格式和open函數(shù)的mode_t
????????????一樣,但可執(zhí)行權(quán)限未使用火诸。
返回值:
????????成功:消息隊(duì)列的標(biāo)識符锦针,失敗:返回-1

查看消息隊(duì)列:

ipcs ‐q

刪除消息隊(duì)列

ipcrm ‐q msqid

3、消息隊(duì)列的信息 格式定義

typedefstruct_msg{
????????long mtype; /*消息類型 必須是第一個成員 必須是long類型*/
????????char mtext[100]; /*消息正文 不止一個成員*/
? ??????... /*消息的正文可以有多個成員*/
}MSG;

4置蜀、發(fā)送消息

#include<sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz,int msgflg);

功能:
????????將新消息添加到消息隊(duì)列奈搜。
參數(shù):
????msqid:消息隊(duì)列的標(biāo)識符。
????msgp:待發(fā)送消息結(jié)構(gòu)體的地址盯荤。
????msgsz:消息正文的字節(jié)數(shù)馋吗。
????msgflg:函數(shù)的控制屬性
????????0:msgsnd調(diào)用阻塞直到條件滿足為止。
????????PC_NOWAIT: 若消息沒有立即發(fā)送則調(diào)用該函數(shù)的進(jìn)程會立即返回秋秤。
返回值:
????????成功:0;失敗:返回-1

5宏粤、接收消息

#include<sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp ,size_t msgsz, long msgtyp,int msgflg);

功能:
? ??????從標(biāo)識符為msqid的消息隊(duì)列中接收一個消息脚翘。一旦接收消息成功,則消息在消息隊(duì)列中被刪除商架。參數(shù):
????????msqid:消息隊(duì)列的標(biāo)識符堰怨,代表要從哪個消息列中獲取消息。
????????msgp: 存放消息結(jié)構(gòu)體的地址蛇摸。
????????msgsz:消息正文的字節(jié)數(shù)备图。
????????msgtyp:感興趣消息的類型、可以有以下幾種類型
????????????msgtyp = 0:返回隊(duì)列中的第一個消息
????????????msgtyp > 0:返回隊(duì)列中消息類型為msgtyp的消息
????????????msgtyp < 0:返回隊(duì)列中消息類型值小于或等于msgtyp絕對值的消息赶袄,如果這種消息有若
? ? ? ? ? ? 干個揽涮,則取類型值最小的消息。
? 注意:
? ? ? ? ? 若消息隊(duì)列中有多種類型的消息饿肺,msgrcv獲取消息的時候按消息類型獲取蒋困,不是先進(jìn)先出的。
? ? ? ? ? 在獲取某類型消息的時候敬辣,若隊(duì)列中有多條此類型的消息雪标,則獲取最先添加的消息,即先進(jìn)先出
? ? ? ? ? msgflg:函數(shù)的控制屬性
? ? ? ? ? 0:msgrcv調(diào)用阻塞直到接收消息成功為止溉跃。
? ? ? ? ? MSG_NOERROR:若返回的消息字節(jié)數(shù)比nbytes字節(jié)數(shù)多,則消息就會截短到nbytes字節(jié),且不通知
? ? ? ? ? 消息發(fā)送進(jìn)程村刨。
? ? ? ? ? IPC_NOWAIT:調(diào)用進(jìn)程會立即返回。若沒有收到消息則立即返回-1撰茎。
返回值:
成功返回讀取消息的長度嵌牺,失敗返回-1

總結(jié):

不管是發(fā)送者還是接收者
? ??????ftok 得到唯一的key
????????msgget 創(chuàng)建消息隊(duì)列

發(fā)送者
? ??????MSG msg;
? ??????msg.mtype = 接收感興趣的類型值;
? ??????msgsnd(msg_id,&msg,sizeof(MSG)‐sizeof(long),0);//發(fā)送消息到消息隊(duì)列

接收者
? ??????MSG msg;
? ??????msgrcv(msg_id,&msg,sizeof(MSG)‐sizeof(long),30,0);
????????msgrcv(msg_id,&msg,sizeof(MSG)‐sizeof(long),接收感興趣的類型值,0);

示例代碼

發(fā)送方

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>?
?#include<sys/msg.h>?
?#include<string.h>?
?//定義一個消息類型結(jié)構(gòu)?
?typedef struct MyStruct
{?
? ? ? long mtype; //消息類型?
????? char mtext[64]; //消息正文?
????? char name[32]; //發(fā)送者的姓名?
?}MSG;?
?int main(int argc,char const*argv[])
?{?
?????????//獲取IPC的唯一KEY值?
? ? ? ? ?key_t key = ftok("/", 2021);?
? ? ? ? ?printf("key=%#x\n", key);?
?????????//創(chuàng)建一個消息隊(duì)列?
????????? int msg_id = msgget(key, IPC_CREAT | 0666);?
????????? printf("msg_id=%d\n", msg_id);?
????????? //發(fā)送消息 給lucy‐‐20發(fā)消息?
????????? MSG msg;?
????????? memset(&msg, 0, sizeof(msg));?
????????? msg.mtype = 30;?
????????? strcpy(msg.name, "bob");?
????????? strcpy(msg.mtext, "hello msg");?
????????? msgsnd(msg_id, &msg, sizeof(MSG) ‐ sizeof(long), 0);
????????? return 0;?
?}

接收方

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
//定義一個消息類型結(jié)構(gòu)?
?typedef struct MyStruct
{
????????long mtype; //消息類型
????????char mtext[64]; //消息正文
????????char name[32]; //發(fā)送者的姓名
}MSG;
int main(int argc,char const*argv[])
{
????????//獲取IPC的唯一KEY值??
? ? ? ? key_t key = ftok("/", 2021);
????????printf("key=%#x\n", key);
????????//創(chuàng)建一個消息隊(duì)列
????????int msg_id = msgget(key, IPC_CREAT | 0666);
????????MSG msg;
????????memset(&msg, 0, sizeof(msg));?
????????msgrcv(msg_id, &msg, sizeof(MSG)‐sizeof(long), 20, 0);
? ? ? ? printf("發(fā)送者:%s\n", msg.name);?
? ? ? ? printf("消息:%s\n", msg.mtext);
????????
????????return 0;?
?}

6、消息隊(duì)列的控制

#include<sys/msg.h>
int msgctl(int msqid,int cmd,struct msqid_ds*buf);

功能:
? ??????對消息隊(duì)列進(jìn)行各種控制龄糊,如修改消息隊(duì)列的屬性逆粹,或刪除消息消息隊(duì)列。
參數(shù):
????????msqid:消息隊(duì)列的標(biāo)識符炫惩。
????????cmd:函數(shù)功能的控制僻弹。
????????buf:msqid_ds數(shù)據(jù)類型的地址,用來存放或更改消息隊(duì)列的屬性他嚷。
????????
????????cmd:函數(shù)功能的控制
????????IPC_RMID:刪除由msqid指示的消息隊(duì)列奢方,將它從系統(tǒng)中刪除并破壞相關(guān)數(shù)據(jù)結(jié)構(gòu)。
????????IPC_STAT:將msqid相關(guān)的數(shù)據(jù)結(jié)構(gòu)中各個元素的當(dāng)前值存入到由buf指向的結(jié)構(gòu)中爸舒。
????????IPC_SET:將msqid相關(guān)的數(shù)據(jù)結(jié)構(gòu)中的元素設(shè)置為由buf指向的結(jié)構(gòu)中的對應(yīng)值壮韭。
返回值:
????成功:返回 0;失敗:返回 ‐1

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肢娘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辛臊,老刑警劉巖滔吠,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡设哗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門两蟀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來网梢,“玉大人,你說我怎么就攤上這事赂毯≌铰玻” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵党涕,是天一觀的道長烦感。 經(jīng)常有香客問我,道長膛堤,這世上最難降的妖魔是什么手趣? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮肥荔,結(jié)果婚禮上绿渣,老公的妹妹穿的比我還像新娘。我一直安慰自己燕耿,他們只是感情好中符,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缸棵,像睡著了一般舟茶。 火紅的嫁衣襯著肌膚如雪谭期。 梳的紋絲不亂的頭發(fā)上堵第,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機(jī)與錄音隧出,去河邊找鬼踏志。 笑死,一個胖子當(dāng)著我的面吹牛胀瞪,可吹牛的內(nèi)容都是我干的针余。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼凄诞,長吁一口氣:“原來是場噩夢啊……” “哼圆雁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起帆谍,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤伪朽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后汛蝙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烈涮,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡朴肺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了坚洽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片戈稿。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖讶舰,靈堂內(nèi)的尸體忽然破棺而出鞍盗,到底是詐尸還是另有隱情,我是刑警寧澤绘雁,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布橡疼,位于F島的核電站,受9級特大地震影響庐舟,放射性物質(zhì)發(fā)生泄漏欣除。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一挪略、第九天 我趴在偏房一處隱蔽的房頂上張望历帚。 院中可真熱鬧,春花似錦杠娱、人聲如沸挽牢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽禽拔。三九已至,卻和暖如春室叉,著一層夾襖步出監(jiān)牢的瞬間睹栖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工茧痕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留野来,地道東北人。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓踪旷,卻偏偏與公主長得像曼氛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子令野,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容