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

消息队列使用的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 条评论
登录 后参与评论

相关文章

来自专栏开发与安全

linux系统编程之文件与I/O(一):文件的打开关闭

一、文件描述符 对于Linux而言,所有对设备或文件的操作都是通过文件描述符进行的。当打开或者创建一个文件的时候,内核向进程返回一个文件描述符(非负整数)。后续...

2359
来自专栏企鹅号快讯

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

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

1989
来自专栏向治洪

android打包方法超过65k错误

近日,Android Developers在Google+上宣布了新的Multidex支持库,为方法总数超过65K的Android应用提供了官方支持。 如果...

1745
来自专栏PingCAP的专栏

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

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

2862
来自专栏林德熙的博客

win10 uwp 轻量级 MVVM 框架入门 2.1.5.3199

一个好的框架是不需要写教程大家看到就会用,但是本金鱼没有那么好的技术,所以需要写很长的博客告诉大家如何使用我的框架。

1032
来自专栏三丰SanFeng

Linux进程间通信(一) - 管道

管道(pipe) 普通的Linux shell都允许重定向,而重定向使用的就是管道。 例如:ps | grep vsftpd .管道是单向的、先进先出的、无结构...

2327
来自专栏北京马哥教育

Linux入侵检查实用指令

1 可以得出filename正在运行的进程 #pidof filename 2 可以通过文件或者tcp udp协议看到进程 #fuser -n tcp port...

3416
来自专栏编程

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

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

2126
来自专栏武培轩的专栏

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

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

3964
来自专栏小筱月

java 开发 websocket 网页端聊天室

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。

4392

扫码关注云+社区