C语言实现支持多线程的循环队列

不多说,直接上代码

头文件: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.支持多线程编程
使用互斥锁,初始化、入队、出队、清空、注销时会加锁、解锁

注意:
使用完毕,千万不要忘记销毁队列,释放内存空间。

源码:
gitee源码:https://gitee.com/brightsu69/cycle-fifo-queue

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bright69

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值