目录
1、环形队列
相比于线性队列,环形队列可以有效避免访问越界问题,使用下标访问队列元素时,到达末尾后下标归0,返回起始位置,使用下标运算即可
array[5],下标为0、1、2、3、4,下标使用(index+1)%array_len计算
环形队列构成:
1、存储容器(数组)
2、Front(头索引)——用于入队,向数组执行下标赋值
3、Rear(尾索引)——用于出队,从数组中获取资源
3、队列大小QUEUE_SIZE
4、已用大小Size
5、环形队列遍历依然采用环形遍历,尾追头
2、生产者消费者
生产者消费者模型,经典的线程同步方式,控制多个线程操作相同任务队列,实现数据传递或任务传递,部分线程添加任务,部分线程获取处理任务,当然需要线程同步技术完成协调调度
生产者用enqueue向环形队列中添加元素,消费者用dequeue从环形队列中读取数据
共享队列为互斥的,需要添加互斥锁
队列未满,生产者添加;队列非空,消费者读取
消费者满,生产者挂起;队列空,消费者挂起
生产者添加任务1次后,唤醒消费者;消费者读取一次数据成功,唤醒1次生产者
环形队列应该为函数指针数据,void*(task*)(void*)——返回值为泛型指针,传入参数为泛型,函数名为task
生产者将函数地址及函数参数添加到环形队列中,消费者传参,调用函数,为任务传递
环形队列数组实现代码
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<pthread.h>
#include<sys/mman.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/fcntl.h>
#include<unistd.h>
#define QUEUE_MAX 10
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t not_full=PTHREAD_COND_INITIALIZER;
pthread_cond_t not_empty=PTHREAD_COND_INITIALIZER;
typedef struct {
int * list;
int Front;
int Rear;
int Size;
int Max;
} q_t;
q_t* queue_init(int Max)
{
q_t* que=NULL;
if((que=(q_t*)malloc(sizeof(q_t)))==NULL)
{
perror("Malloc failed");
return NULL;
}
if((que->list=(int*)malloc(sizeof(int)*Max))==NULL)
{
perror("Malloc List failed");
return NULL;
}
bzero(que->list,sizeof(int)*Max);
que->Front=0;
que->Rear=0;
que->Size=0;
que->Max=Max;
}
bool if_Empty(q_t *ptr) {
return ptr->Size == 0;
}
bool if_Full(q_t *ptr) {
return ptr->Size == QUEUE_MAX;
}
bool enqueue(q_t *ptr, int value) {
if (if_Full(ptr))
{
return false;
}
ptr->list[ptr->Rear] = value;
ptr->Rear = (ptr->Rear + 1) % QUEUE_MAX;
ptr->Size++;
return true;
}
bool dequeue(q_t *ptr, int *value) {
if (if_Empty(ptr))
{
return false;
}
*value = ptr->list[ptr->Front];
ptr->Front = (ptr->Front + 1) % QUEUE_MAX;
ptr->Size--;
return true;
}
void* Customer(void* arg)
{
pthread_detach(pthread_self());
q_t* que=NULL;
que=(q_t*)arg;
pthread_mutex_lock(&lock);
if(if_Empty(que))
{
pthread_cond_wait(¬_empty,&lock);
}
int value;
dequeue(que,&value);
pthread_mutex_unlock(&lock);
printf("customer thread 0x%x,dequeue value %d\n",(int)pthread_self(),value);
pthread_cond_signal(¬_full);
pthread_exit(NULL);
}
int producer_add(q_t* que,int value)
{
pthread_mutex_lock(&lock);
if(if_Full(que))
{
pthread_cond_wait(¬_full,&lock);
}
enqueue(que,value);
pthread_mutex_unlock(&lock);
pthread_cond_signal(¬_empty);
return 0;
}
int main()
{
q_t* q=NULL;
int value;
pthread_t tids[8];
q=queue_init(50);
for(int i=0;i<8;i++)
{
pthread_create(&tids[i],NULL,Customer,(void*)q);
}
for(int i=0;i<8;i++)
{
int index=rand()%8-1;
producer_add(q,index);
}
while(1)
sleep(1);
return 0;
}