消息队列简记

简介:

消息队列简记


在了解了信号量共享内存之后,消息队列自然就比较容易理解了。

之前提到共享内存的操作不是原子的, 那么便可以结合信号量来进行控制。

消息队列是另外一种进程间通信的手段, 使用以下几个函数调用。

        #include <sys/types.h>

        #include <sys/ipc.h>

        #include <sys/msg.h>//一般上述两个头文件都被此文件包含

        int msgget(key_t key, int msgflg);

        int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

        ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

        int msgctl(int msqid, int cmd, struct msqid_ds *buf);

由此可见几种IPC機制都是类似的。


msgget(key, msgflg);

        同样的道理,该函数创建或获取一个和key相关的消息队列,一般使用 0666 | IPC_CREAT作为msgflg的值。看到0666很容易想到777(关于chmod),很容易可以知道是设置权限。

操作的是低9位, 666就是110110110。从高到低对应着u(用戶),g(组别), o(其他)的读、写和执行权限。比如最高三位110表示u有读和写权限,但没有执行权限。

函数返回一个msgid,供其它相关函数使用。


msgsnd(msgid, msgp, msgsz, msgflg);

        一般来说,消息队列中的消息成员都是一个结构体,该结构体至少包含两个成员: 一个是消息类型,另一个是消息数据。

比如:

#define MSGSIZ 1024 struct msg_st { long msg_type; char msg_text[MSGSIZ]; };

        而msgp就是指向要传送的消息的指针。

        msgsz是消息的大小,不包含消息类型。

        msgflg一般置0。


msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);

        与msgsnd类似,不同的是第4个参数msgtyp。

        msgtyp指定了要接收的消息类型, 一共有3种情况。

                1. msgtyp为0, 表示按顺序接收消息队列中的成员。

                2. msgtyp为某正数,表示接收类型为该正数的消息,类型由消息结构体中的msg_type指定。

                3. msgtyp为某负数,表示接收类型小于等于该负数绝对值的类型消息。

        msgctl一般用来撤销消息队列,形如 msgctl(msgid, IPC_RMID, 0)。

        下面是个小实验:

用于发送消息的msg1.c:

#include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/msg.h> #include "msg_st.h" int main(){ int i; int msg_id; char buf[MSGSIZ]; struct msg_st msg_ptr; msg_id = msgget((key_t)1234, 0666 |IPC_CREAT); for(i=0; i<3; i++){ printf("请輸入第%d条要发送的消息:", i); scanf("%s", buf); msg_ptr.msg_type = i; strcpy(msg_ptr.msg_text, buf); msgsnd(msg_id, (void *)&msg_ptr, 512, 0); } printf("已发送完消息./n"); return 0; }

用于接收消息的msg2.c(指定接收数据类型为1的消息):

#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/msg.h> #include "msg_st.h" int main(int argc, char *argv[]){ int msg_id; struct msg_st msg_ptr; msg_ptr.msg_type = 1; msg_id = msgget((key_t)1234, 0666 | IPC_CREAT); printf("要接收的消息类型为%ld/n", msg_ptr.msg_type); msgrcv(msg_id, (void *)&msg_ptr, 512, msg_ptr.msg_type, 0); printf("接收到的消息为:%s/n", msg_ptr.msg_text); msgctl(msg_id, IPC_RMID, 0); return 0; }


Jason Lee

2009-11-16 p.m

目录
相关文章
|
5月前
|
消息中间件 缓存 网络协议
无锁消息队列的设计实现
无锁消息队列的设计实现
51 2
|
3月前
|
消息中间件 存储 Kafka
现代消息队列与云存储问题之现代消息队列处理消息顺序性的问题如何解决
现代消息队列与云存储问题之现代消息队列处理消息顺序性的问题如何解决
|
5月前
|
消息中间件 存储 负载均衡
消息队列 MQ产品使用合集之POP消费模式是否可以保证消息顺序性
阿里云消息队列MQ(Message Queue)是一种高可用、高性能的消息中间件服务,它允许您在分布式应用的不同组件之间异步传递消息,从而实现系统解耦、流量削峰填谷以及提高系统的可扩展性和灵活性。以下是使用阿里云消息队列MQ产品的关键点和最佳实践合集。
|
消息中间件 中间件
mq消息队列的作用
mq消息队列的作用
118 0
|
消息中间件 存储 RocketMQ
自顶向下学习 RocketMQ(四):顺序消息
顺序消息是消息队列 RocketMQ 提供的一种对消息发送和消费顺序有严格要求的消息。对于一个指定的 Topic,消息严格按照先进先出(FIFO)的原则进行消息发布和消费,即先发布的消息先消费,后发布的消息后消费。
自顶向下学习 RocketMQ(四):顺序消息
|
消息中间件 存储 监控
消息队列与任务队列的区别
消息队列和任务队列是我们在软件系统中常常遇到的概念。尽管它们的名字相似,但实际上它们有不同的用途和工作原理。本文将介绍消息队列和任务队列之间的区别。
564 0
|
消息中间件 监控 大数据
高并发设计系列-消息队列篇
高并发设计系列-消息队列篇
|
消息中间件 存储 搜索推荐
如何设计一个消息队列?
**如果让你来设计一个 MQ,该如何下手?需要考虑哪些问题?又有哪些技术挑战?** 对于 MQ 来说,不管是 RocketMQ、Kafka 还是其他消息队列,**它们的本质都是:一发一存一消费。**下面我们以这个本质作为根,一起由浅入深地聊聊 MQ。
1290 2
|
消息中间件 关系型数据库 MySQL
5. 消息队列中,如何保证消息的顺序性?
5. 消息队列中,如何保证消息的顺序性?
585 0
5. 消息队列中,如何保证消息的顺序性?
|
消息中间件 缓存 容灾
22. 为什么需要消息队列?使用消息队列有什么好处?
22. 为什么需要消息队列?使用消息队列有什么好处?
178 0
22. 为什么需要消息队列?使用消息队列有什么好处?