做婚庆网站有哪些内容,商城网站怎么建,郑州郑东新区网站建设,做网站公司费用在之前的博客中给出了设计循环队列的思路以及源码#xff0c;这些可都是经过我长期大数据测试的验证哦。当然#xff0c;现在的很多开源项目和一些封装好的类或接口也都有类似的队列实现方法#xff0c;之所以我还在使用自己写的这一套方法#xff0c;主要是因为灵活性较大…在之前的博客中给出了设计循环队列的思路以及源码这些可都是经过我长期大数据测试的验证哦。当然现在的很多开源项目和一些封装好的类或接口也都有类似的队列实现方法之所以我还在使用自己写的这一套方法主要是因为灵活性较大我可以定制出适合自己的接口。而且在其上的操作逻辑和结果我也心知肚明。 好了之所以隔了这么久写这个第三篇文章主要是考虑到以下因素 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 (SoldierJazz163.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语言实现三》