在之前的博客中给出了设计循环队列的思路以及源码,这些可都是经过我长期大数据测试的验证哦。当然,现在的很多开源项目和一些封装好的类或接口也都有类似的队列实现方法,之所以我还在使用自己写的这一套方法,主要是因为灵活性较大,我可以定制出适合自己的接口。而且在其上的操作逻辑和结果我也心知肚明。
好了,之所以隔了这么久写这个第三篇文章,主要是考虑到以下因素:
<1> 队列并发操作的同步问题;(安全性)
<2> 部分情况下,希望在读取队列后进行队列回写操作。(比如进行数据分析按一帧一帧进行解析的时候,发现队列里缓存数据不足一帧,此时就需要回写,等再有数据保存到队列)

下面先提出 <1> 的解决方法,使用互斥锁和信号量,给出简单例子:

Exp1:

pthread_mutex_init(&mutex);thread1:...pthread_mutex_lock(&mutex);WriteQueue(q, wbuf, writelen);pthread_mutex_unlock(&mutex);...thread2:...pthread_mutex_lock(&mutex);ReadQueue(q, rbuf, &readlen);pthread_mutex_unlock(&mutex);...

Exp2:

sem_init(&sem);thread1:...sem_wait(&sem);WriteQueue(q, wbuf, writelen);sem_post(&sem);...thread2:...sem_wait(&sem);ReadQueue(q, rbuf, &readlen);sem_post(&sem);...

其他的方式还有很多啦,就不一一列举了,小型项目开发应该是足够了。

至于方案 <2> 的解决方法,在 queue.c 中添加一个回写函数就好啦,原理也很简单,把读指针移动到之前的位置就可以啦。需要考虑的就是回写的长度大于队列当前读指针距离队列头的位置时的处理,详细可以参见我下面的代码:

unsigned int RecoverReadQueue(Queue *q, unsigned int len)
{unsigned int ret = 0;unsigned int rest = q->read;if (rest >= len){q->read -= len;}else{q->read = q->size - (len - rest);}q->space -= len;return ret;
}

为了防止部分读者忽略了之前文章,我还是把最新的源码贴出来以供参考:

queue.h

#ifndef _QUEUE_H
#define _QUEUE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>/*** Queue - queue structure* @buf: queue buffer* @read: position of read* @write: position of write* @size: buffer size* @space: writable buffer size*/
typedef struct {unsigned char *buf;unsigned int read;unsigned int write;unsigned int size;unsigned int space;bool OverFlow;
} Queue;#define Avail(q) (q->size - q->space)extern bool Queue_Empty(Queue *q);
extern bool Queue_Full(Queue *q);
extern unsigned int RecoverReadQueue(Queue *q, unsigned int len);
extern void Queue_Init(Queue *q, int size);
extern void Queue_Destroy(Queue *q);
extern bool AddQueue(Queue *q, unsigned char val);
extern bool DelQueue(Queue *q, unsigned char *val);
extern unsigned int WriteQueue(Queue *q, unsigned char *buf, unsigned int len);
extern unsigned int ReadQueue(Queue *q, unsigned char *buf, unsigned int len);#endif

queue.c

/** Queue operation API - 1.1** Copyright (C) 2016 SoldierJazz (SoldierJazz@163.com)** This program is free software; you can redistribute it and/or* modify it. **/#include "queue.h"/*** Queue_Init - init a queue* @q: pointer of queue* @size: size of buffer in queue** Must be called when started. */
void Queue_Init(Queue *q, int size)
{q->buf = (unsigned char *)malloc(sizeof(unsigned char) * size);memset(q->buf, 0x00, size);q->read = 0;q->write = 0;q->size = size;q->space = size;q->OverFlow = false;
}/*** Queue_Destroy - destroy a queue* @q: pointer of queue*/
void Queue_Destroy(Queue *q)
{free(q->buf);
}/*** Queue_Empty - tests whether a queue is empty* @q: the queue to test*/
bool Queue_Empty(Queue *q)
{
    return (q->space == q->size);
}/*** Queue_Full - tests whether a queue is full* @q: the queue to test*/
bool Queue_Full(Queue *q)
{
    return (q->space == 0);
}/*** AddQueue - add a byte to queue* @q: the queue to add to* @val: the char to add*/
bool
bool AddQueue(Queue *q, unsigned char val)
{if (!Queue_Full(q)) {q->buf[q->write] = val;q->write = (q->write + 1) % q->size;q->space--;
        return true;}
    return false;
}/*** DelQueue - delete a byte from queue* @q: the queue to delete from* @val: the char deleted*/
bool DelQueue(Queue *q, unsigned char *val)
{if (!Queue_Empty(q)) {*val = q->buf[q->read];q->read = (q->read + 1) % q->size;q->space++;
        return true;}
    return false;
}/*** WriteQueue - write buffers to queue* @q: the queue to write in* @buf: pointer of write buffer* @len: length of write buffer*/
unsigned int WriteQueue(Queue *q, unsigned char *buf, unsigned int len)
{unsigned int ret = 0;unsigned int rest = q->size - q->write;if (!Queue_Full(q)) {if (q->space >= len) {ret = len;if (rest >= len) {memcpy(q->buf + q->write, buf, len);q->write = (q->write + len) % q->size;q->space -= len;} else {memcpy(q->buf + q->write, buf, rest);q->write = 0;memcpy(q->buf, buf + rest, len - rest);q->write = len -rest;q->space -= len;}} else {ret = q->space;if (rest >= q->space) {memcpy(q->buf + q->write, buf, q->space);q->write = (q->write + q->space) % q->size;q->space = 0;} else {memcpy(q->buf + q->write, buf, rest);q->write = 0;memcpy(q->buf, buf + rest, q->space - rest);q->write = q->space -rest;q->space = 0;}}   }
    return ret;
}/*** RecoverReadQueue - recover len of buffer from queue* @q: the queue to recover from* @len: recover length*/
unsigned int RecoverReadQueue(Queue *q, unsigned int len)
{unsigned int ret = 0;unsigned int rest = q->read;if (rest >= len){q->read -= len;}else{q->read = q->size - (len - rest);}q->space -= len;
return ret;
}/*** ReadQueue - read buffers from queue* @q: the queue to read from* @buf: pointer of read buffer* @len: read length*/
unsigned int ReadQueue(Queue *q, unsigned char *buf, unsigned int len)
{unsigned int rest = q->size - q->read;unsigned int ret = 0;if (!Queue_Empty(q)) {if (Avail(q) >= len) {ret = len;if (rest >= len) {memcpy(buf, q->buf + q->read, len);q->read = (q->read + len) % q->size;q->space += len;} else {memcpy(buf, q->buf + q->read, rest);q->read = 0;memcpy(buf + rest, q->buf, len - rest);q->read = len -rest;q->space += len;}
            return len;} else {ret = Avail(q);if (rest >= Avail(q)) {memcpy(buf, q->buf + q->read, Avail(q));q->read = (q->read + Avail(q)) % q->size;q->space = q->size;} else {memcpy(buf, q->buf + q->read, rest);q->read = 0;memcpy(buf + rest, q->buf, Avail(q) - rest);q->read = Avail(q) -rest;q->space = q->size;}}}
    return ret;
}

关于循环队列主题的系列文章,可移步至以下链接:
1. 《循环队列及C语言实现<一>》
2. 《循环队列及C语言实现<二>》
3. 《循环队列及C语言实现<三>》

循环队列及C语言实现三相关推荐

  1. 循环队列及C语言实现二

    在我的上一篇博文中已经讲到循环队列的特点作用以及C语言实现,当然实现和操作的方式比较简单,在实际项目应用中略显粗糙.因此,这一篇提供一个进阶篇的实现与操作接口.具体函数作用可以参见我的注释部分,使用的 ...

  2. 循环队列及C语言实现一

    循环队列是为了充分利用内存,进行数据操作的一种基本算法.具体实现方式可划分为:链式队列和静态队列,这里所谓的静态是指在一片连续的内存区域进行数据操作.本文只讲述静态队列,也是最简单的实现方式,链式队列 ...

  3. 循环队列c语言的实现,循环队列的C语言实现

    生活中有很多队列的影子,比如打饭排队,买火车票排队问题等,可以说与时间相关的问题,一般都会涉及到队列问题:从生活中,可以抽象出队列的概念,队列就是一个能够实现"先进先出"的存储结构 ...

  4. 数据结构(严蔚敏)之五——循环队列(c语言实现)

    在这里我先强调几点概念: 1.在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置. 2.在单队列中我们判断队列是否为空的条件是:Q.front==Q.rear;而在循环队列 ...

  5. 顺序循环队列类c#语言,C#--循环队列的顺序存储

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  6. leetcode 622——设计循环队列

    leetcode 622--设计循环队列(C语言提交) 题目链接:leetcode 622--设计循环队列 题目描述: 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先 ...

  7. c语言数组方式实现静态循环队列

    1 循环队列原理图 2 结构体设计 3 运行结果图 4 完整源代码 #include<stdio.h> #include<malloc.h> /*这是一个c语言用数组方式实现循 ...

  8. 循环队列–C语言实现–数据结构

    循环队列–C语言实现–数据结构 目录 循环队列C语言实现数据结构 目录 一 要求 二 循环队列 三 循环队列的算法设计 1 建立循环队列 2 置空队列 3 入队 4 出队 5 打印队 四 程序 1 程 ...

  9. c语言循环队列入列算法,C语言——循环队列和链队列的基本运算

    // 循环队列 #include #include "SeqQue.h" // 循环队列的基本运算 /* const int maxsize = 20; typedef struc ...

最新文章

  1. qregexp限制数字范围_计算一列数字的平均值
  2. Linux的cat、more、less有什么区别
  3. [Deep-Learning-with-Python]神经网络入手学习[上]
  4. Android中的数据存储方式
  5. 基于PyTorch搭建CNN实现视频动作分类任务代码详解
  6. 使用OpenCV可视化Intel Realsensen D435 深度图为彩色图
  7. 使用NUnit做单元测试(总结版)
  8. oracle unpivot 索引_oracle pivot 和 unpivot 函数的使用
  9. 微软将开源查询处理工具Trill,怎么下载部署?
  10. 常用排序算法-java实现(插入,快排)
  11. spring整合大全
  12. Linux上RandomAccessFile访问FTP文件出错
  13. 【TWVRP】基于matlab蚁群算法求解带时间窗的多中心车辆路径规划问题【含Matlab源码 112期】
  14. 从我的客户谈营销公司怎样将创业企业做大的
  15. PHP怎么计算百分比?PHP计算百分比的写法
  16. python使用Jpype调用java程序
  17. python jinja2_Python jinja2
  18. shopex mysql 数据库服务器_[日记] shopex转移以及MySql简单操作命令
  19. 100以内的奇数和是多少_一百以内所有奇数和偶数有哪些
  20. proteus8.9仿真闪退怎么解决?如何找到ProgramData?

热门文章

  1. cxxtest单元测试框架源码分析(二):所有对外功能实现分析
  2. 发一个flash+PHP的简单上传代码
  3. sql优化技巧_使用这些查询优化技巧成为SQL向导
  4. 服务器虚拟化网口,服务器安装虚拟网口
  5. FCN全卷积网络随笔
  6. 莫烦Matplotlib可视化第二章基本使用代码学习
  7. 如何使用Ionic和Firebase在短短三天内创建冠状病毒跟踪器应用程序
  8. [习题].FindControl()方法 与 PlaceHolder控件 #2(动态加入「子控件」的事件)
  9. 应用容器公共免费部署平台
  10. Effective STL中文版pdf