进程同步(四)—— 消息队列

消息队列使用的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 }

测试结果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏上善若水

P001PHP开发之PHP实现取得HTTP请求的原文相关信息

通过以下代码示例,我们可以知道,PHP如何获得请求的URL及请求的头部,body等具体信息;

11920
来自专栏软件开发

WebSocket与消息推送

B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为...

85650
来自专栏PingCAP的专栏

TiKV 是如何存取数据的(上)

本文会详细的介绍 TiKV 是如何处理读写请求的,通过该文档,同学们会知道 TiKV 是如何将一个写请求包含的数据更改存储到系统,并且能读出对应的数据的。

44720
来自专栏企鹅号快讯

修复 Linux/Unix/OS X/BSD 系统控制台上的显示乱码

有时我的探索会在屏幕上输出一些奇怪的东西。比如,有一次我不小心用 cat 命令查看了一下二进制文件的内容 —— cat /sbin/*。这种情况下你将无法再访问...

20890
来自专栏Youngxj

安卓四大组件之ContentProvider-内容提供者

23630
来自专栏用户画像

虚拟存储器

9410
来自专栏武培轩的专栏

数据库事务的四大特性以及隔离级别

本篇文章主要介绍数据库事务的四大特性ACID,以及数据库的隔离级别。 事务 概念 事务指的是满足 ACID 特性的一系列操作。在数据库中,可以通过 Commit...

41440
来自专栏转载gongluck的CSDN博客

打开文件open()函数的使用方法详解

头文件:#include <sys/types.h>    #include <sys/stat.h>    #include <fcntl.h> 定义函数...

31250
来自专栏lgp20151222

Maven常用命令

10920
来自专栏Android群英传

一个字符解决Gradle aar编译参数传递问题是怎样一种体验

8910

扫码关注云+社区

领取腾讯云代金券