链表多线程

语言实现多线程下的链表队列
项目中需要一个链表,线程A进行入队操作(生产者),线程B进行查询、出队操作(消费者),同时希望线程B在队列为空时阻塞,降低cpu负载,因此考虑用pthread_cond_wait进行实现:

主要实现功能:

1)出队和入队的加锁

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

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

头文件:

#ifndef Queue_H
#define Queue_H
#include <stdlib.h>
#include <pthread.h>
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->frontNULL&&pqueue->rearNULL&&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;
}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值