消息队列使用的API与信号量、共享内存类似。 消息队列、信号量、共享内存均可用ipcs命令查看以及ipcrm删除。
msgget首先向内核获取一个消息队列ID。 获取成功后,可用msgctl获取和设置队列相关信息。 msgsnd用于写消息队列。 msgrcv用于读消息队列。
消息队列遵循First In ,First Out规则。 下面是消息队列相关实现代码。
1 //queuewrite.cpp
2 #include <sys/types.h>
3 #include <sys/msg.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <iostream>
7
8 using namespace std;
9
10 const int MSGQUEUE = 0x8769;
11 class msgQueue
12 {
13 public:
14 void initQueue();
15 int getQueueLen();
16 void addMsg(char *msgbuf);
17 int revMsg();
18 void releaseQueue();
19 private:
20 int m_queueID;
21 };
22
23 void msgQueue::initQueue()
24 {
25 m_queueID = msgget(MSGQUEUE, 0600|IPC_CREAT);
26 if (m_queueID == -1)
27 cout<<"msgget error!";
28 }
29 int msgQueue::getQueueLen()
30 {
31 struct msqid_ds buf;
32 int ret = msgctl(m_queueID, IPC_STAT, &buf);
33 if (ret == -1)
34 {
35 cout<<"get queue len failure!";
36 return ret;
37 }
38 return buf.msg_qnum;
39 }
40 void msgQueue::addMsg(char *msgbuf)
41 {
42 struct msgbuf buf;
43 buf.mtype = 1;
44 memcpy(buf.mtext, msgbuf, sizeof(msgbuf));
45 int ret = msgsnd(m_queueID, &buf, sizeof(buf), IPC_NOWAIT);
46 if (ret != 0)
47 {
48 cout<<"send msg error!";
49 return;
50 }
51 }
52 int msgQueue::revMsg()
53 {
54 struct msgbuf buf;
55 int ret = msgrcv(m_queueID, &buf, sizeof(buf), 0, 0);
56 if (ret == -1)
57 {
58 return 0;
59 }
60 cout<<buf.mtext;
61 return 1;
62 }
63 void msgQueue::releaseQueue()
64 {
65 msgctl(m_queueID,IPC_RMID,0);
66 }
67 int main()
68 {
69 msgQueue FIFO;
70 char buf[512];
71 FIFO.initQueue();
72 while(1)
73 {
74 cin>>buf;
75 FIFO.addMsg(buf);
76 }
77 return 0;
78 }
执行后向消息队列插入内容,使用ipcs -q命令查看。
读消息队列只需修改main函数如下:
1 int main()
2 {
3 msgQueue FIFO;
4 FIFO.initQueue();
5 int queLen = FIFO.getQueueLen();
6 while(queLen--)
7 {
8 FIFO.revMsg();
9 }
10 return 0;
11 }
测试结果: