基于上一节顺序循环队列来实现生产者消费者问题
主要变化就是把需要操作的资源变成操作循环队列,代码如下:
circularQueue.h
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define FREE(p) \ if (p != NULL) {\ free(p);\ p = NULL;\ } typedef struct{ //int data[QUEUE_SIZE]; //队列中的元素 int *data; int cqHead; //指向队首元素 int cqTail; //指向队尾元素 int size; //当前队列的大小 int maxSize; //可以容纳的最大大小 }CIRCULAR_QUEUE, *P_CIRCULAR_QUEUE; int IsQueEmpty(P_CIRCULAR_QUEUE cQue); int IsQueFull(P_CIRCULAR_QUEUE cQue); int getQueueSize(P_CIRCULAR_QUEUE cQue); int getQueueHead(P_CIRCULAR_QUEUE cQue); int getQueueHeadData(P_CIRCULAR_QUEUE cQue); int getQueueTail(P_CIRCULAR_QUEUE cQue); int getQueueTailData(P_CIRCULAR_QUEUE cQue); //队列是先进先出FIFO void InitCircularQue(P_CIRCULAR_QUEUE cQue, int maxsize); void enterCircularQue(P_CIRCULAR_QUEUE cQue, int elem); int leaveCircularQue(P_CIRCULAR_QUEUE cQue); void ShowQue(P_CIRCULAR_QUEUE cQue); void delQue(P_CIRCULAR_QUEUE cQue);
circularQueue.c
/*初始化:head = tail = 0; * 队列空:head == tail; * 队列满:(tail + 1) % MaxSize == head; * 元素数:num = (tail - head + MaxSize) % MaxSize * */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include "circularQueue.h" //判断循环队列是否为空 int IsQueEmpty(P_CIRCULAR_QUEUE cQue) { return cQue->cqHead == cQue->cqTail; } //判断循环队列是否满 int IsQueFull(P_CIRCULAR_QUEUE cQue) { //为了区分队空的情况和队满的情况,使用+1来空出一个数据 return (cQue->cqTail + 1) % cQue->maxSize == cQue->cqHead; } //获取循环队列的大小 int getQueueSize(P_CIRCULAR_QUEUE cQue) { cQue->size = (cQue->cqTail - cQue->cqHead + cQue->maxSize) % cQue->maxSize; printf("cqTail[%d], cqHead[%d], size[%d]\n", cQue->cqTail, cQue->cqHead, cQue->size); return cQue->size; } //获取循环队列队首的位置 int getQueueHead(P_CIRCULAR_QUEUE cQue) { return cQue->cqHead; } //获取循环队列队首元素 int getQueueHeadData(P_CIRCULAR_QUEUE cQue) { return cQue->data[cQue->cqHead]; } //获取循环队列队尾的位置 int getQueueTail(P_CIRCULAR_QUEUE cQue) { return cQue->cqTail; } //获取循环队列队首元素 int getQueueTailData(P_CIRCULAR_QUEUE cQue) { return cQue->data[cQue->cqTail]; } //初始化循环队列 void InitCircularQue(P_CIRCULAR_QUEUE cQue, int maxsize) { printf("cque size =%zu\n", sizeof(*cQue)); cQue->data = (int*)malloc(sizeof(int)*maxsize); //memset(cQue, 0, sizeof(*cQue)); cQue->cqTail = 0; cQue->cqHead = 0; cQue->size = 0; cQue->maxSize = maxsize; printf("cqHead[%d], cqTail[%d], maxSize[%d]\n", cQue->cqHead, cQue->cqTail, cQue->maxSize); } //向循环队列中插入元素 void enterCircularQue(P_CIRCULAR_QUEUE cQue, int elem) { if(IsQueFull(cQue)) { printf("Elem %d can't push to CircularQueue %p (Full)!\n", elem, cQue); return; } //cQue->data[cQue->cqTail] = elem; int *p = cQue->data; p[cQue->cqTail] = elem; cQue->cqTail = (cQue->cqTail + 1)%cQue->maxSize; printf("cqTail ==%d \n", cQue->cqTail); } //从循环队列中取数据 int leaveCircularQue(P_CIRCULAR_QUEUE cQue) { if(IsQueEmpty(cQue)) { printf("Queue %p is Empty! \n", cQue); return -1; } int elem = cQue->data[cQue->cqHead]; cQue->cqHead = (cQue->cqHead + 1)%cQue->maxSize; printf("cqHead == %d \n", cQue->cqHead); return elem; } //显示队列中的所有元素 void ShowQue(P_CIRCULAR_QUEUE cQue) { if(IsQueEmpty(cQue)) { printf("Queue %p is Empty! \n", cQue); return ; } printf("CircularQueue Element: "); int elemIdx = cQue->cqHead; while((elemIdx % cQue->maxSize) != cQue->cqTail) printf("%d ", cQue->data[(elemIdx++) % cQue->maxSize]); printf("\n"); } void delQue(P_CIRCULAR_QUEUE cQue) { cQue->cqTail = cQue->cqHead = 0; FREE(cQue->data); }