redis是数据库还是中间件 c#消息队列实际应用

由于最近的工作中需要用到消息队列,顺带花时间整理了一下 。
C语言消息队列,有三种,一种是System V ipc,第二种的是posix ipc,第三种是自己用代码实现的消息队列 。
System V ipc 和Posix ipc 也叫进程间通信 。(IPC的全称是Inter-process Comminication,就是进程间通信) 。
进程间通信分为三个内容,分别是:消息队列、信号量和共享内存 。
System V IPC也分为以下三种类型:
System V 消息队列
System V 信号量
System V 共享内存区

redis是数据库还是中间件 c#消息队列实际应用


System V IPC 三种类型
本文将主要介绍System V 消息队列
在System V IPC中,System v ipc中有一个重要的类型是key_t,在msget、semget、shmget函数操作中都需要利用这个类型是参数 。
key_t的值由函数ftok来生成,函数ftok把一个[已存在的路径名,pathname]和一个[整数标识符,id]转换称一个key_t值, 称为IPC键 。
key_t ftok(const char *pathname, int proj_id);
System V 消息队列消息队列函数由msgget、msgctl、msgsnd、msgrcv四个函数组成 。
1.msgget函数原型
redis是数据库还是中间件 c#消息队列实际应用


msgget函数原型
如果用msgget创建了一个新的消息队列对象时,则msqid_ds结构成员变量的值设置如下:
msg_qnum、msg_lspid、msg_lrpid、 msg_stime、msg_rtime设置为0 。
msg_ctime设置为当前时间 。
msg_qbytes设成系统的限制值 。
msgflg的读写权限写入msg_perm.mode中 。
msg_perm结构的uid和cuid成员被设置成当前进程的有效用户ID,gid和cuid成员被设置成当前进程的有效组ID 。
2.msgctl函数原型
redis是数据库还是中间件 c#消息队列实际应用


msgctl函数原型
3.msgsnd函数原型
redis是数据库还是中间件 c#消息队列实际应用


msgsnd函数原型
msgsnd()为阻塞函数,当消息队列容量满或消息个数满会阻塞 。消息队列已被删除,则返回EIDRM错误;被信号中断返回E_INTR错误 。
如果设置IPC_NOWAIT消息队列满或个数满时会返回-1,并且置EAGAIN错误 。
msgsnd()解除阻塞的条件有以下三个条件:
① 不满足消息队列满或个数满两个条件,即消息队列中有容纳该消息的空间 。
② msqid代表的消息队列被删除 。
③ 调用msgsnd函数的进程被信号中断 。
4.msgrcv函数原型
redis是数据库还是中间件 c#消息队列实际应用


msgrcv函数原型
msgrcv()解除阻塞的条件有以下三个:
① 消息队列中有了满足条件的消息 。
② msqid代表的消息队列被删除 。
③ 调用msgrcv()的进程被信号中断 。
消息队列使用程序范例
msgrcv.c
#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<stdio.h>struct msgbuf{long type;int groupid;int appid;char buf[1024];};int main(){int msgid;msgid=msgget(0x1000,IPC_CREAT | 0777);struct msgbuf mb;msgrcv(msgid,&mb,sizeof(struct msgbuf)-sizeof(long),1,0);printf("type: %dtgroupid: %dtappid: %dn", mb.type,mb.groupid, mb.appid);puts(mb.buf);}msgsnd.c
#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<stdio.h>struct msgbuf{long type;//类型int groupid;int appid;char buf[1024];};int main(){int msgid;msgid=msgget(0x1000,IPC_CREAT | 0777);struct msgbuf mb={1,1,1,"hello world"};int ret;ret=msgsnd(msgid,&mb,sizeof(struct msgbuf)-sizeof(long),0);//这里的长度不包括类型的大小}测试
redis是数据库还是中间件 c#消息队列实际应用

推荐阅读