概念
- 底層是一個(gè)鏈隊(duì)列
- 與共享內(nèi)存的不同是:內(nèi)核要保證消息隊(duì)列的FIFO性質(zhì)枫夺,因此當(dāng)有多個(gè)接收方進(jìn)程接收消息隊(duì)列中的消息的時(shí)候昭殉,不會(huì)產(chǎn)生沖突忙干,由內(nèi)核來(lái)協(xié)調(diào)他們的執(zhí)行順序上祈。由于隊(duì)列性質(zhì)培遵,隊(duì)尾寫挣磨,隊(duì)頭讀,所以讀寫也不會(huì)存在沖突荤懂。
API和涉及的數(shù)據(jù)結(jié)構(gòu)
創(chuàng)建消息隊(duì)列
#include <sys/msg.h>
int msgget(key_t key,int flag);
參數(shù)和返回值類比共享內(nèi)存shmget
發(fā)送消息
#include <sys/msg.h>
int msgsnd(int msqid,void * ptr,size_t nbytes,int flag);
參數(shù)表:
msqid:消息隊(duì)列ID
ptr:指向待發(fā)送的消息的指針
nbytes:消息的大小
flag:當(dāng)消息隊(duì)列滿時(shí)如何處理(IPC_NOWAIT?)
返回值:
0:成功
-1:失敗
- 消息結(jié)構(gòu)體:
msgsnd結(jié)構(gòu)體中的ptr指向要發(fā)送的信息,此信息是一個(gè)結(jié)構(gòu)體塘砸,需要用戶自己定義节仿,但是必須包含消息類型和消息的內(nèi)容,例如下
struct mymsg
{
long msgtype;
char msgtext[MAXLENTH];
}
接收信息
#include <sys/msg.h>
int msgrcv(int msqid,void * ptr,size_t nbytes,long type,int flag);
參數(shù)表:
msqid:消息隊(duì)列ID
ptr:指向待發(fā)送的消息的指針
nbytes:消息的大小
type:消息類型
flag:當(dāng)消息隊(duì)列滿時(shí)如何處理(NOWAIT?)
返回值:
大于0:消息中數(shù)據(jù)部分的長(zhǎng)度
-1:失敗
- 消息類型的用法
type = 0時(shí)掉蔬,返回隊(duì)列中的第一個(gè)消息
type > 0時(shí)廊宪,返回隊(duì)列中消息類型為type的第一個(gè)消息
type < 0時(shí),返回消息隊(duì)列中類型值小于或等于type的消息女轿,若有多個(gè)箭启,則返回最小的
注意數(shù)據(jù)大小要滿足:消息隊(duì)列定義的消息信息大小>=msgrcv中的數(shù)據(jù)大小>=msgsnd中的數(shù)據(jù)大小(即MAXLENTH>=msgrcv中nbytes>=msgsnd中的nbytes
消息隊(duì)列操作
#include <sys/msg.h>
int msg(int msqid,int cmd,struct msqid_ds * buf);
參數(shù)表:
msqid:消息隊(duì)列ID
cmd:待執(zhí)行的操作
buf:存放消息隊(duì)列屬性的內(nèi)存地址
返回值:
0:成功
-1:失敗
示例代碼
寫端:創(chuàng)建消息隊(duì)列,發(fā)送消息
#include <sys/msg.h>
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <sys/ipc.h>
using namespace std;
#define MAXLENTH 128
struct msg_st
{
int msg_type;
char msg_text[MAXLENTH];
};
int main()
{
int msg_id;
int key = ftok(".",512);
char buf[10];
struct msg_st sndMsg;
sndMsg.msg_type = 1;
msg_id = msgget(key,IPC_CREAT|0666);
if(msg_id == -1)
{
perror("msgget");
exit(EXIT_FAILURE);
}
cin >> buf;
strcpy(sndMsg.msg_text,buf);
if(msgsnd(msg_id,(void *)&sndMsg,10,0)==-1)
{
perror("msgsnd");
exit(EXIT_FAILURE);
}
sleep(10);
return 0;
}
讀端:接收信息蛉迹,刪除消息隊(duì)列
#include <sys/msg.h>
#include <iostream>
#include <sys/ipc.h>
#include <cstring>
using namespace std;
#define MAXLENTH 128
struct msg_st
{
int msg_type;
char msg_text[MAXLENTH];
};
int main()
{
int msg_id;
int key = ftok(".",512);
char buf[100];
struct msg_st rcvMsg;
msg_id = msgget(key,0666);
if(msg_id == -1)
{
perror("msgget");
exit(EXIT_FAILURE);
}
if(msgrcv(msg_id,(void *)&rcvMsg,20,0,0)==-1)
{
perror("msgrcv");
exit(EXIT_FAILURE);
}
cout <<rcvMsg.msg_text <<endl;
msgctl(msg_id,IPC_RMID,0);
return 0;
}