Linux高阶——1116—环形队列&&生产者消费者

目录

1、环形队列

2、生产者消费者

环形队列数组实现代码

成功截图


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(&not_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(&not_full);
    pthread_exit(NULL);
}

int producer_add(q_t* que,int value)
{
    pthread_mutex_lock(&lock);
    if(if_Full(que))
    {
        pthread_cond_wait(&not_full,&lock);
    }
    enqueue(que,value);
    pthread_mutex_unlock(&lock);
    pthread_cond_signal(&not_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;
}

成功截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值