消息队列使用的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 }
测试结果: