不多说,直接上代码
头文件:cyclefifo.h
/*
cyclefifo.h
Function: cycle FIFO queue, can be used on multiple threads mode.
Author: suwei
Version: 0.0.1
Usage:
1) Initialize a cycle fifo queue
eg:
Cfqueue myQueue;
cfqInit(&myQueue, 5); //maximus size of queue is 5
2) Declare an object, which you want to push into the queue
eg:
CString strA = "element 0"
3) In some threads, push the object into queue
eg:
cfqPush(&myQueue, (char *) &strA);
4) ... (do others)
5) In some other threads, get the object from the queue
eg:
CString strB = (CString *) cfqPop(&myQueue);
7) ... (do others)
8) destory the queue (must do this)
eg:
cfqDestory(myQueue);
*/
#ifndef CYCLEFIFOQUEUE_H
#define CYCLEFIFOQUEUE_H
#include <pthread.h>
#include <string.h>
typedef struct cycle_fifo_queue {
unsigned int front; //队首
unsigned int rear; //队尾
unsigned int count; //元素个数
pthread_mutex_t lock; //多线程锁
char** data; //元素存储区
}Cfqueue;
//队列初始化
int cfqInit(Cfqueue* ptr, int size);
//队列是否满载,TRUE:满,FALSE:未满
bool cfqIsFull(Cfqueue* ptr);
//队列是否为空,TRUE:空,FALSE:非空
bool cfqIsEmpty(Cfqueue* ptr);
//元素入队
int cfqPush(Cfqueue* ptr, char* item);
//元素出队
char* cfqPop(Cfqueue* ptr);
//获取队列长度
int cfqGetQlength (Cfqueue* ptr);
//销毁队列
void cfqDestory(Cfqueue* ptr);
//清空队列
void cfqClean(Cfqueue* ptr);
#endif
C文件:cyclefifo.c
#include "cyclefifo.h"
#include <iostream>
static int qSize = 0;
//初始化队列
int cfqInit(Cfqueue* ptr, int size) {
qSize=size;
ptr->data = new char* [qSize];
if ( ptr->data == NULL ) {
return -1;
}
memset(ptr->data, 0 , sizeof(ptr->data));
ptr->front = 0;
ptr->rear = -1;
ptr->count = 0;
pthread_mutex_init(&ptr->lock, NULL);
return 0;
}
//检查队列是否已满
bool cfqIsFull(Cfqueue* ptr) {
return ptr->count >= qSize;
}
//检查队列是否为空
bool cfqIsEmpty(Cfqueue* ptr) {
return ptr->count <= 0;
}
//入队
int cfqPush(Cfqueue* ptr, char* item) {
pthread_mutex_lock(&ptr->lock);
if (cfqIsFull(ptr)) {
pthread_mutex_unlock(&ptr->lock);
return -1;//ERR_CYCLEFIFOQUEUE_ISFULL;
}
else {
ptr->count++;
ptr->rear = (ptr->rear + 1) % qSize;
ptr->data[ptr->rear] = item;
}
pthread_mutex_unlock(&ptr->lock);
return 0;
}
//出队
char* cfqPop(Cfqueue* ptr) {
char* ret = NULL;
pthread_mutex_lock(&ptr->lock);
if (cfqIsEmpty(ptr)) {
pthread_mutex_unlock(&ptr->lock);
return NULL;
} else {
ret = ptr->data[ptr->front];
ptr->count --;
ptr->front = (ptr->front + 1) % qSize;
}
pthread_mutex_unlock(&ptr->lock);
return ret;
}
//返回队列长度
int cfqGetQlength (Cfqueue* ptr) {
return ptr->count;
}
//清空队列
void cfqClean(Cfqueue* ptr) {
pthread_mutex_lock(&ptr->lock);
if(cfqIsEmpty(ptr)) {
pthread_mutex_unlock(&ptr->lock);
return;
}else {
memset(ptr->data, 0 , sizeof(ptr->data));
ptr->front = 0;
ptr->rear = -1;
ptr->count = 0;
}
pthread_mutex_unlock(&ptr->lock);
return;
}
//销毁
void cfqDestory(Cfqueue* ptr) {
pthread_mutex_lock(&ptr->lock);
if (ptr->data) {
delete[]ptr->data;
ptr->data = NULL;
ptr->rear = ptr->front = 0;
}
pthread_mutex_unlock(&ptr->lock);
pthread_mutex_destroy(&ptr->lock);
return;
}
测试程序: test.cpp
#include "msginfo.h" //队列中的元素
#include "cyclefifo.h"
int main(int argc, char* argv[]){
CMsginfo msginfo;
msginfo.setSid("0x0078");
CMsginfo *p_msginfo = &msginfo;
char* pp = (char*) p_msginfo;
CMsginfo *pt = (CMsginfo *) pp;
std::cout << "--------------------------------------------------------------------" << std::endl;
Cfqueue recvQueue;
cfqInit(&recvQueue, 10);
cfqPush(&recvQueue, pp);
CMsginfo msginfo2;
msginfo2.setSid("0x0080");
cfqPush(&recvQueue, (char*) &msginfo2);
char* qq = cfqPop(&recvQueue);
CMsginfo *qt = (CMsginfo *) qq;
std::string str_get2=qt->getSid();
std::cout << "in main 1 sid=" << str_get2 << std::endl;
std::cout << "3elements in queue = " << cfqGetQlength(&recvQueue) << std::endl;
std::string str_get3=((CMsginfo *) cfqPop(&recvQueue))->getSid();
std::cout << "in main 1 sid=" << str_get3 << std::endl;
std::cout << "3elements in queue = " << cfqGetQlength(&recvQueue) << std::endl;
cfqDestory(&recvQueue);
return 0;
}
执行结果:
--------------------------------------------------------------------
elements in queue (1st push) = 1
elements in queue (2nd push) =2
sid=0x0078
elements in queue (1st pop) = 1
sid=0x0080
elements in queue (2nd pop) = 0
几个特点:
1.循环队列的长度可以自定义
初始化时的size参数
2.队列中的元素可以是任何类型
队列中存储的是指针,而指针指向的数据类型,可以由用户自行定义
3.支持多线程编程
使用互斥锁,初始化、入队、出队、清空、注销时会加锁、解锁
注意:
使用完毕,千万不要忘记销毁队列,释放内存空间。