消息队列简记

简介:

消息队列简记


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

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

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

        #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

目录
相关文章
|
8月前
|
消息中间件 中间件
mq消息队列的作用
mq消息队列的作用
90 0
|
7月前
|
消息中间件 大数据 Kafka
消息队列使用优缺点和各种MQ适用场景
消息队列使用优缺点和各种MQ适用场景
166 0
|
9月前
|
消息中间件 Kafka RocketMQ
3. 消息队列的优缺点?
3. 消息队列的优缺点?
44 0
|
9月前
|
消息中间件 存储 监控
消息队列优点
消息队列优点
|
9月前
|
消息中间件 监控 大数据
高并发设计系列-消息队列篇
高并发设计系列-消息队列篇
|
消息中间件 存储 RocketMQ
自顶向下学习 RocketMQ(四):顺序消息
顺序消息是消息队列 RocketMQ 提供的一种对消息发送和消费顺序有严格要求的消息。对于一个指定的 Topic,消息严格按照先进先出(FIFO)的原则进行消息发布和消费,即先发布的消息先消费,后发布的消息后消费。
自顶向下学习 RocketMQ(四):顺序消息
|
消息中间件 NoSQL 关系型数据库
|
消息中间件 存储 搜索推荐
如何设计一个消息队列?
**如果让你来设计一个 MQ,该如何下手?需要考虑哪些问题?又有哪些技术挑战?** 对于 MQ 来说,不管是 RocketMQ、Kafka 还是其他消息队列,**它们的本质都是:一发一存一消费。**下面我们以这个本质作为根,一起由浅入深地聊聊 MQ。
899 0
|
消息中间件 缓存 容灾
22. 为什么需要消息队列?使用消息队列有什么好处?
22. 为什么需要消息队列?使用消息队列有什么好处?
145 0
22. 为什么需要消息队列?使用消息队列有什么好处?
|
消息中间件 关系型数据库 MySQL
5. 消息队列中,如何保证消息的顺序性?
5. 消息队列中,如何保证消息的顺序性?
444 0
5. 消息队列中,如何保证消息的顺序性?

热门文章

最新文章