基于上一节顺序循环队列来实现生产者消费者问题

主要变化就是把需要操作的资源变成操作循环队列,代码如下:

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);

}
View Code

相关文章: