赞
踩
队列是一种非常好用的数据结构,消息队列可以提高业务逻辑的成功率,在Unix/Linux下,消息队列还是进程之间通信的一种技术方案,关于队列数据结构的知识点,可以参考之前的文章:
深入理解数据结构(一):队列
队列的功能虽然很好用,但是编写一个稳健的消息队列功能,还是有些难度的,本文参考uC/OS 操作系统的队列代码原理,编写了消息队列 功能。
使用时可以将cQueue.h和cQueue.c 包含到自己的工程代码中,调用API接口函数,即可实现消息队列的管理,具体的可以参考代码库中的example.c 。
由于定义的消息队列中的消息类型为 void 型,所以可以传入自定义的消息类型,比如自定义结构体。
代码库位置如下:
github : cQueue
gitee : cQueue
cQueue using the cQueue struct data type:
/*---------------The cQueue structure ------------------------------------------------------------*/
typedef struct cQueue{
void **QMemory; /* pointer to message queue storage area */
void **QStart; /* pointer to start of queue data */
void **QEnd; /* pointer to end of queue data */
void **QIn; /* pointer to where next message will be inserted in the queue */
void **QOut; /* pointer to where next message will be extracted from the queue */
int QSize; /* size of queue -- max number of entries */
int QEntries; /* current number of entries in the queue */
} cQueue_t;
/* * Description : 创建并初始化1个队列结构 * @para[in] : size 消息队列的大小,最多存放消息队列的条数 * @return : 消息队列指针 */ cQueue_t *cQcreate(int size); /* * Description : 删除消息队列,并释放消息队列申请的内存区域 * @para[in] : pq 消息队列指针 * @return : NULL */ void cQDelete(cQueue_t *pq); /* * Description : 清空消息队列 * @para[in] : pq 消息队列指针 * @return : NULL */ void cQFlush(cQueue_t *pq); /* * Description : 从消息队列中接收消息 * @para[in] : pq 消息队列指针 * @para[out] : perr 接收消息错误标志,0-无;1-消息队列为空。 * @return : 接收到的消息指针 */ void *cQRcv(cQueue_t *pq, char *perr); /* * Description : 向消息队列中发送消息 * @para[in] : pq 消息队列指针 * @para[in] : pmsg 要发送的消息指针 * @return : ERR_Q_NONE 发送成功 * ERR_Q_FULL 发送失败,当前消息队列已满 */ int cQPost(cQueue_t *pq, void *pmsg); /* * Description : 向消息队列头部发送消息,使用该发送功能,允许发送优先级高的消息,相当于 * 在最前面插入消息,这样下次读取消息队列时,读到的是刚刚发送的这条消息。 * * @para[in] : pq 消息队列指针 * @para[in] : pmsg 要发送的消息指针 * * @return : ERR_Q_NONE 发送成功 * ERR_Q_FULL 发送失败,当前消息队列已满。 */ int cQPostFront(cQueue_t *pq, void *pmsg);
#include <stdio.h> #include <stdlib.h> #include "cQueue.h" int main(int argc, char *argv[]) { int i,j; int *pmsg; char perr; cQueue_t *pq; int *prx; /* 创建1个长度为110的消息队列 */ pq = cQcreate(110); /* cQPost ...*/ for(i = 0; i < 100; i++){ pmsg = (int *)malloc(10*sizeof(int)); for(j = 0; j < 10; j++){ pmsg[j] = i*10 + j; } cQPost(pq, (void *)pmsg); } /* cQPostFront...*/ pmsg = (int *)malloc(10*sizeof(int)); for(j = 0; j < 10; j++){ pmsg[j] = 1000 + j; } cQPostFront(pq, (void *)pmsg); /* cQRcv...*/ for(j = 0; j < 101; j++){ prx = (int *)cQRcv(pq, &perr); printf("prx%3d:", j); for(i = 0; i < 10; i++){ printf("<%4d>", prx[i]); } printf("\n"); } /* 删除消息队列 */ cQDelete(pq); return 0; }
1、cQueue的实现没有考虑到消息队列的读/写限制,在使用过程中,如果业务逻辑涉及到对消息队列访问的“同步/互斥”,还是要结合具体的使用环境来添加“同步/互斥”条件。
2、为了兼容性,cQueue中消息的类型均为void,所以向消息队列插入消息时,强制转换为(void *),而读取消息时,则要进行显性的转换,转换成我们自定义的消息类型。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。