进出队C语言不用链表,c语言实现多线程下的链表队列

项目中需要一个链表,线程A进行入队操作,线程B进行查询出队操作,同时不希望线程B在队列为空时阻塞,降低cpu负载,因此考虑用pthread_cond_wait进行实现:

主要实现功能:

1)出队和入队的加锁

2)当有元素入队时唤醒线程B

3)队列为空时线程B进入休眠

头文件:

#ifndef Queue_H

#define Queue_H

#include

#include

typedef char* Frame;

typedef struct node * PNode;

typedef struct node

{

Frame frame;

PNode next;

}Node;

typedef struct

{

PNode front;

PNode rear;

int size;

pthread_mutex_t q_lock;

pthread_cond_t cond;

}Queue;

/*构造一个空队列*/

Queue *InitQueue();

/*销毁一个队列*/

void DestroyQueue(Queue *pqueue);

/*清空一个队列*/

void ClearQueue(Queue *pqueue);

/*判断队列是否为空*/

int IsEmpty(Queue *pqueue);

/*返回队列大小*/

int GetSize(Queue *pqueue);

/*返回队头元素*/

PNode GetFront(Queue *pqueue, Frame *frame);

/*返回队尾元素*/

PNode GetRear(Queue *pqueue, Frame *frame);

/*将新元素入队*/

PNode EnQueue(Queue *pqueue,Frame frame);

/*队头元素出队*/

PNode DeQueue(Queue *pqueue);

/*遍历队列并对各数据项调用visit函数*/

void QueueTraverse(Queue *pqueue,void (*visit)());

#endif

c文件:

#include"Queue.h"

/*构造一个空队列*/

Queue *InitQueue()

{

Queue *pqueue = (Queue *)malloc(sizeof(Queue));

if(pqueue!=NULL)

{

pqueue->front = NULL;

pqueue->rear = NULL;

pqueue->size = 0;

pthread_mutex_init(&pqueue->q_lock, NULL);

pthread_cond_init(&pqueue->cond, NULL);

}

return pqueue;

}

/*销毁一个队列*/

void DestroyQueue(Queue *pqueue)

{

if(!pqueue)

return;

ClearQueue(pqueue);

pthread_mutex_destroy(&pqueue->q_lock);

pthread_cond_destroy(&pqueue->cond);

free(pqueue);

pqueue = NULL;

}

/*清空一个队列*/

void ClearQueue(Queue *pqueue)

{

while(!IsEmpty(pqueue)) {

DeQueue(pqueue);

}

}

/*判断队列是否为空*/

int IsEmpty(Queue *pqueue)

{

if(pqueue->front==NULL&&pqueue->rear==NULL&&pqueue->size==0)

return 1;

else

return 0;

}

/*返回队列大小*/

int GetSize(Queue *pqueue)

{

return pqueue->size;

}

/*返回队头元素*/

PNode GetFront(Queue *pqueue, Frame *frame)

{

pthread_mutex_lock(&pqueue->q_lock);

/*

if(!IsEmpty(pqueue))

{

*frame = pqueue->front->frame;

}else {

pthread_cond_wait(&pqueue->cond, &pqueue->q_lock);

}*/

while(IsEmpty(pqueue))

pthread_cond_wait(&pqueue->cond, &pqueue->q_lock);

*frame = pqueue->front->frame;

pthread_mutex_unlock(&pqueue->q_lock);

return pqueue->front;//---->此处有bug,队列为空时,在锁释放后,pqueue->front可能被入队操作赋值,出现frame等于NULL,而pqueue->front不等于NULL

}

/*返回队尾元素*/

PNode GetRear(Queue *pqueue, Frame *frame)

{

if(!IsEmpty(pqueue)) {

*frame = pqueue->rear->frame;

}

return pqueue->rear;

}

/*将新元素入队*/

PNode EnQueue(Queue *pqueue, Frame frame)

{

PNode pnode = (PNode)malloc(sizeof(Node));

if(pnode != NULL) {

pnode->frame = frame;

pnode->next = NULL;

pthread_mutex_lock(&pqueue->q_lock);

if(IsEmpty(pqueue)) {

pqueue->front = pnode;

} else {

pqueue->rear->next = pnode;

}

pqueue->rear = pnode;

pqueue->size++;

pthread_cond_signal(&pqueue->cond);

pthread_mutex_unlock(&pqueue->q_lock);

}

return pnode;

}

/*队头元素出队*/

PNode DeQueue(Queue *pqueue)

{

PNode pnode = pqueue->front;

pthread_mutex_lock(&pqueue->q_lock);

if(!IsEmpty(pqueue)) {

pqueue->size--;

pqueue->front = pnode->next;

free(pnode);

if(pqueue->size==0)

pqueue->rear = NULL;

}

pthread_mutex_unlock(&pqueue->q_lock);

return pqueue->front;

}

/*遍历队列并对各数据项调用visit函数*/

void QueueTraverse(Queue *pqueue, void (*visit)())

{

PNode pnode = pqueue->front;

int i = pqueue->size;

while(i--)

{

visit(pnode->frame);

pnode = pnode->next;

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值