Linux下進(jìn)程通訊消息隊(duì)列
?MQ(message queue),從字面意思上看,本質(zhì)是個(gè)隊(duì)列,F(xiàn)IFO 先入先出,只不過隊(duì)列中存放的內(nèi)容是message 而已。MQ 是在消息的傳輸過程中保存消息的容器。多用于分布式系統(tǒng)之間進(jìn)行通信。
消息隊(duì)列與 FIFO 很相似,都是一個(gè)隊(duì)列結(jié)構(gòu),都可以有多個(gè)進(jìn)程往隊(duì)列里面寫信息,多個(gè)進(jìn)程從隊(duì)列中讀取信息。
1.查看消息隊(duì)列命令
??1.查看消息隊(duì)列:ipcs -q
[wbyq@wbyq ~]$ ipcs -q
--------- 消息隊(duì)列 -----------
鍵 msqid 擁有者 權(quán)限 已用字節(jié)數(shù) 消息
0xb8104ad9 1 wbyq 644 0 0
0xd2350093 2 wbyq 666 208 2
??2.查看消息隊(duì)列限制信息:ipcs -lq
[wbyq@wbyq ~]$ ipcs -lq
---------- 消息限制 -----------
系統(tǒng)最大隊(duì)列數(shù)量 = 32000
最大消息尺寸 (字節(jié)) = 8192
默認(rèn)的隊(duì)列最大尺寸 (字節(jié)) = 16384
??3.查看消息隊(duì)列詳細(xì)信息:ipcs -q -i
[wbyq@wbyq ~]$ ipcs -q -i 2
消息隊(duì)列 msqid=2
uid=1000 gid=1000 cuid=1000 cgid=1000 模式=0666
cbytes=208 qbytes=16384 qnum=2 lspid=10177 lrpid=10175
發(fā)送時(shí)間=Thu Apr 28 11:56:08 2022
接收時(shí)間=Thu Apr 28 11:56:08 2022
更改時(shí)間=Thu Apr 28 11:49:04 2022
??4.創(chuàng)建消息隊(duì)列:ipcmk -Q
[wbyq@wbyq ~]$ ipcmk -Q
消息隊(duì)列 id:4
[wbyq@wbyq ~]$ ipcs -q
--------- 消息隊(duì)列 -----------
鍵 msqid 擁有者 權(quán)限 已用字節(jié)數(shù) 消息
0xb8104ad9 1 wbyq 644 0 0
0xd2350093 2 wbyq 666 208 2
0x05ae2c01 4 wbyq 644 0 0
5.刪除信號(hào)量:ipcrm -q
[wbyq@wbyq ~]$ ipcrm -q 4
[wbyq@wbyq ~]$ ipcs -q
--------- 消息隊(duì)列 -----------
鍵 msqid 擁有者 權(quán)限 已用字節(jié)數(shù) 消息
0xb8104ad9 1 wbyq 644 0 0
0xd2350093 2 wbyq 666 208 2
2.相關(guān)函數(shù)
#include
#include
#include
int msgget(key_t key, int msgflg);
函數(shù)功能:創(chuàng)建消息隊(duì)列
形參:key 鍵值,ftok產(chǎn)生
? ? ?msgflg?標(biāo)志 IPC_CREAT|0666
返回值:失敗返回-1,成功返回msqid
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
函數(shù)功能: 將消息添加到隊(duì)列中
形參:msqid msgget函數(shù)返回值
???msgp 消息內(nèi)容數(shù)據(jù),一般以結(jié)構(gòu)體類型填充
??????struct msgbuf {
????????????long mtype; /* 消息類型, 必須 > 0 */
????????????char mtext[1]; /消息數(shù)據(jù)/
????????????};
??????注意:struct msgbuf必須自己重寫,第一個(gè)參數(shù)long mtype必須指定,且>0,其他類型自定義
???msgsz 消息字節(jié)數(shù),大小為:sizeof(struct msgbuf)-sizeof(mtype);
???msgflg 0當(dāng)隊(duì)列滿時(shí)阻塞,直到消息寫入成功
??????IPC_NOWAIT 當(dāng)隊(duì)列滿時(shí)不阻塞,立刻返回
??????IPC_NOERROR 若發(fā)送的消息大于 size 字節(jié),則把該消息截?cái)?,截?cái)嗖糠謱⒈粊G棄,且不通知發(fā)送進(jìn)程。
返回值:成功返回0,失敗返回-1;
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
函數(shù)功能:從隊(duì)列中取出消息
形參:msqid msgget函數(shù)返回值
???msgp 存放讀取到的消息內(nèi)容
???msgsz 消息字節(jié)數(shù),大小為:sizeof(struct msgbuf)-sizeof(mtype);
???msgtyp 消息類型:
???????>0 接收對(duì)列中的第 1 個(gè)類型等于 msgtyp 的消息
???????==0 取出消息隊(duì)列中的第一條消息
???????<0 接收其類型小于或等于 msgtyp 絕對(duì)值的第 1 個(gè)最低類型消息
???msgflg 0 當(dāng)隊(duì)列空時(shí)阻塞,或者消息類型不匹配時(shí)阻塞
?????? IPC_NOWAIT 不阻塞,立刻返回
?????? IPC_NOERROR 若發(fā)送的消息大于 size 字節(jié),則把該消息截?cái)?,截?cái)嗖糠謱⒈粊G棄,且不通知發(fā)送進(jìn)程。
返回值:成功返回讀取的字節(jié)數(shù),失敗返回-1;
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
函數(shù)功能:控制函數(shù)
形參:msqid msgget函數(shù)返回值
???cmd 通常為 IPC_RMID 表示刪除消息隊(duì)列。
當(dāng)刪除消息隊(duì)列時(shí),則buf填NULL即可;
3.示例
??(1)創(chuàng)建消息隊(duì)列,添加消息到隊(duì)列
#include
#include
#include
#include
#include
#include
#include
struct msgbuf
{
long mtype;//消息類型,必須>0
int cnt;
char buff[100];
};
int main(int argc,char *argv[])
{
if(argc!=4)
{
printf("格式:./app <消息類型> <消息數(shù)據(jù)> <消息內(nèi)容>\n");
return 0;
}
key_t key=ftok("msgsnd.c", 1234);//生成鍵值
if(key==-1)
{
printf("生成鍵值失敗err=%s\n",strerror(errno));
return 0;
}
printf("key=%#x\n",key);
int msqid=msgget(key,IPC_CREAT|0666);//創(chuàng)建消息隊(duì)列
if(msqid==-1)
{
printf("創(chuàng)建消息隊(duì)列失敗err=%s\n",strerror(errno));
return 0;
}
printf("msqid=%d\n",msqid);
struct msgbuf msg;
msg.mtype=atoi(argv[1]);//消息類型
msg.cnt=atoi(argv[2]);//消息數(shù)據(jù)
strcpy(msg.buff,argv[3]);//消息內(nèi)容
int msg_size=sizeof(msg)-sizeof(long);//消息大小,總大小-消息類型大小
/*添加消息到隊(duì)列*/
int size=msgsnd(msqid,&msg,msg_size,0);
if(size==-1)
{
printf("寫入消息失敗err=%s\n",strerror(errno));
}
else printf("消息寫入成功\n");
return 0;
}
??(2)從隊(duì)列中取消息
#include
#include
#include
#include
#include
#include
#include
struct msgbuf
{
long mtype;//消息類型,必須>0
int cnt;
char buff[100];
};
int main(int argc,char *argv[])
{
if(argc!=2)
{
printf("格式:./app <消息類型>\n");
return 0;
}
key_t key=ftok("msgsnd.c", 1234);//生成鍵值
if(key==-1)
{
printf("生成鍵值失敗err=%s\n",strerror(errno));
return 0;
}
printf("key=%#x\n",key);
int msqid=msgget(key,IPC_CREAT|0666);//創(chuàng)建消息隊(duì)列
if(msqid==-1)
{
printf("創(chuàng)建消息隊(duì)列失敗err=%s\n",strerror(errno));
return 0;
}
printf("msqid=%d\n",msqid);
struct msgbuf msg;
int msg_size=sizeof(msg)-sizeof(long);//消息大小
long msgtyp=atoi(argv[1]);//要寫讀取的消息類型
//從消息隊(duì)列中取數(shù)據(jù)
ssize_t size=msgrcv(msqid,&msg,msg_size,msgtyp,0);
if(size==-1)
{
printf("讀取消息失敗err=%s\n",strerror(errno));
}
else
{
printf("------------讀取消息成功size:%ld----------------\n",size);
printf("\tmtype=%ld\n",msg.mtype);
printf("\tcnt=%d\n",msg.cnt);
printf("\tbuff=%s\n",msg.buff);
}
return 0;
}
??(3)運(yùn)行效果
-
Linux
+關(guān)注
關(guān)注
87文章
11212瀏覽量
208721 -
IPC
+關(guān)注
關(guān)注
3文章
337瀏覽量
51772 -
進(jìn)程
+關(guān)注
關(guān)注
0文章
201瀏覽量
13938
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論