阻塞队列的实现源码

1.BlockQueue.hpp

#pragma once
#include <iostream>
#include <pthread.h>
#include <mutex>
#include <queue>
#include <unistd.h>
//STL容器存在线程安全问题

const int gDefaultCap = 5;//最大容量capacity

template<class T>
class BlockQueue
{
private:
    bool isQueueEmpty()
    {
        return _bq.size() == 0;
    }
    bool isQueueFull()
    {
        return _bq.size() == _capacity;
    }
public:
    BlockQueue(int capacity = gDefaultCap):_capacity(capacity)
    {
        pthread_mutex_init(&_mtx, nullptr);
        pthread_cond_init(&_isFull, nullptr);
        pthread_cond_init(&_isEmpty, nullptr);
    }

    void Push(const T& in)
    {
        pthread_mutex_lock(&_mtx);
        // 1.先检测当前临界资源是否满足临界条件
        // pthread_cond_wait:第二个参数是一把锁,成功调用wait之后,传入的锁会自动释放
        // 从哪里阻塞挂起,就从哪里唤醒
        // 唤醒时pthread_cond_wait会自动获取锁
        while(isQueueFull()) pthread_cond_wait(&_isFull, &_mtx);
        // 2.访问临界资源
        _bq.push(in);
        // if(_bq.size() >= _capacity/2) pthread_cond_signal(&_isEmpty);
        pthread_cond_signal(&_isEmpty);
        pthread_mutex_unlock(&_mtx);
    }

    void Pop(T* out)
    {
        pthread_mutex_lock(&_mtx);
        while(isQueueEmpty()) pthread_cond_wait(&_isEmpty, &_mtx);

        *out = _bq.front();
        _bq.pop();
        pthread_cond_signal(&_isFull);//安全的
        pthread_mutex_unlock(&_mtx);
    }

    ~BlockQueue()
    {
        pthread_mutex_destroy(&_mtx);
        pthread_cond_destroy(&_isEmpty);
        pthread_cond_destroy(&_isEmpty);
    }
private:
    std::queue<T> _bq;       // 阻塞队列
    int _capacity;           // 容量上限
    pthread_mutex_t _mtx;    // 通过互斥锁保证队列安全
    pthread_cond_t _isEmpty; // 表示阻塞队列是否为空的条件
    pthread_cond_t _isFull;  // 表示阻塞队列是否为满的条件
};

2.ConProd.cc

#include "BlockQueue.hpp"

void* consumer(void *args)
{
    BlockQueue<int> *bqueue = (BlockQueue<int> *)args;
    while(true)
    {
        int a;
        bqueue->Pop(&a);
        std::cout << "消费一个数据:" << a << std::endl;
        sleep(1);
    }
    return nullptr;
}

void* productor(void *args)
{
    BlockQueue<int> *bqueue = (BlockQueue<int> *)args;
    int a = 1;
    while(true)
    {
        bqueue->Push(a);
        std::cout << "生产一个数据:" << a << std::endl;
        a++;
    }
    return nullptr;
}

int main()
{
    BlockQueue<int> *bqueue = new BlockQueue<int>();
    pthread_t c, p; // pthread_create最后一个参数为传入的数据
    pthread_create(&c, nullptr, consumer, bqueue);
    pthread_create(&p, nullptr, productor, bqueue);

    pthread_join(c, nullptr);
    pthread_join(p, nullptr);

    delete bqueue;
    return 0;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

new出新对象

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值