相關函數
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
創建消息隊列
int msgget(key_t key, int msgflg);
創建或者打開一個消息隊列,成功返回消息隊列的句柄,失敗返回-1
需要提供給函數key(鍵值)和msgflag操作類型。
所有使用這個消息隊列的進程需要使用相同的鍵值(一個整形數字),保證打開的是同一個消息隊列。
操作類型參數的范圍:
/* Mode bits for `msgget', `semget', and `shmget'. */
#define IPC_CREAT 01000 /* Create key if key does not exist. */
#define IPC_EXCL 02000 /* Fail if key exists. */
#define IPC_NOWAIT 04000 /* Return error on wait. */
向消息隊列中發送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//成功返回0,失敗返回-1
參數:
msgid 消息隊列的句柄,
msgp 要發送的消息結構體指針,
msgsz 發送的消息大小(不包括消息類型),
msgflag 操作類型
解釋:
當消息隊列中空間被占滿時,msgsnd會被阻塞住。但可以將msgflag設置為IPC_NOWAIT,當消息隊列滿時,會立即返回錯誤。
從消息隊列中接收消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
//成功返回接收到的長度,失敗返回-1
參數:
msgid 消息隊列的句柄
msgp 接收消息存放位置
msgsz 接收的消息大小
msgtype 消息類型
msgflag 操作類型
參數解釋:
msgtype=0 接收消息隊列中的第一條消息
msgtype>0 接收消息隊列中消息類型等於msgtype的第一條消息
msgtype<0 接收消息隊列中類型值小於msgtype絕對值的第一條消息
接收的msgflag操作類型參數,一般設置為0,可以讓隊列中沒有消息時,接收一直阻塞。
消息隊列的控制
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
參數:
msgid 消息隊列句柄
cmd 命令,一般使用IPC_RMID刪除消息隊列
buf 一般為NULL
消息結構體
結構體可以自己定義,但是最前的成員必須是一個long型數據,表示消息類型。
代碼
send.c
#define MSGKEY 1001
#define MSG_TYPE 1
struct msgbuf
{
long mtype; /* message type, must be > 0 */
double Lat;
double Lon;
double Hgt;
};
int main()
{
int msgid;
int ret;
struct msgbuf mbuf;
msgid = msgget(MSGKEY, 0); //打開消息隊列
if (-1 == msgid)
{
perror("msgget");
exit(1);
}
{
for(unsigned int i=0;i<10;i++)
{
mbuf.Lat += 10.11;
mbuf.Hgt += 100.0;
mbuf.mtype = MSG_TYPE;
ret = msgsnd(msgid, &mbuf, sizeof(mbuf)-sizeof(mbuf.mtype), 0);
if (-1 == ret)
{
perror("msgsnd");
exit(1);
}
sleep(1);
}
}
sleep(1);
msgctl(msgid, IPC_RMID, NULL);//銷毀消息隊列
return 0;
}
recv.c
#define MSGKEY 1001
#define MSG_TYPE 1
struct msgbuf
{
long mtype; /* message type, must be > 0 */
double Lat;
double Lon;
double Hgt;
};
int main()
{
int msgid;
int ret;
struct msgbuf mbuf;
msgid = msgget(MSGKEY, IPC_CREAT | IPC_EXCL); //打開消息隊列,如果已經存在則報錯
if (-1 == msgid)
{
perror("msgget");
exit(1);
}
while (1)
{
memset(&mbuf, 0, sizeof(mbuf));
ret = msgrcv(msgid, &mbuf, sizeof(mbuf)-sizeof(mbuf.mtype), MSG_TYPE,0);
if (-1 == ret)
{
perror("msgrcv");
exit(1);
}
printf("queue recv Lat=%lf,Lon=%lf,Hgt=%lf\n",mbuf.Lat, mbuf.Lon, mbuf.Hgt);
}
return 0;
}