zoukankan      html  css  js  c++  java
  • 后端程序员之路 41、BlockingQueue

    BlockingQueue,阻塞队列,常用于实现生产者和消费者模型
    特点:
    1、队列为空时,取操作会等到队列有数据
    2、队列满时,存操作会等到队列可用

    基于C++11的阻塞队列简单实现 - Cynric 的博客 - 博客频道 - CSDN.NET
    http://blog.csdn.net/cywosp/article/details/9157379


    参考java的阻塞队列实现,还可以有以下细节:
    1、ArrayBlockingQueue
    用数组来存队列里的数据,可以避免用链表时额外的node对象创建销毁开销
    2、LinkedBlockingQueue
    最常用,队列可以有无限容量,但是生产速度过快会爆掉内存
    3、DelayQueue
    node只有延迟时间到了才能取到,存操作不会阻塞
    4、PriorityBlockingQueue
    类似DelayQueue,传入Compator来决定优先级
    5、SynchronousQueue
    没有缓冲的等待队列

    BlockingQueue - - ITeye技术网站
    http://wsmajunfeng.iteye.com/blog/1629354

    最终实现的简单BlockingQueue:

    #include <semaphore.h>
    #include <stdio.h>
    #include <errno.h>
    #include <pthread.h>
    #include <list>

    template<class T> class BlockingQueue {
    public:
        std::list<T> _queue;
        size_t _curr_size;
        pthread_mutex_t _lock;
        sem_t _consumer_sem;
        sem_t _producer_sem;
        int _max_size;

    public:
        BlockingQueue(int max_size) {
            pthread_mutex_init(&_lock, NULL);
            sem_init(&_consumer_sem, 0, 0);
            _max_size = max_size;
            _curr_size = 0;
            if (max_size > 0) {
                sem_init(&_producer_sem, 0, max_size);
            }
        }

        ~BlockingQueue() {
            pthread_mutex_destroy(&_lock);
            sem_destroy(&_consumer_sem);
            if (_max_size > 0) {
                sem_destroy(&_producer_sem);
            }
        }

        void push(const T& value) {
            if (_max_size > 0) {
                sem_wait(&_producer_sem);
            }

            pthread_mutex_lock(&_lock);
            _queue.push_back(value);
            ++_curr_size;
            sem_post(&_consumer_sem);
            pthread_mutex_unlock(&_lock);
        }

        void batch_push(const std::vector<T>& values) {
            for (uint32_t i = 0; i < values.size(); ++i) {
                push( values[i] );
            }
        }
        
        T take() {
            sem_wait(&_consumer_sem);
            pthread_mutex_lock(&_lock);
            T value = _queue.front();
            _queue.pop_front();
            --_curr_size;
            if (_max_size > 0) {
                sem_post(&_producer_sem);
            }
            pthread_mutex_unlock(&_lock);
            return value;
        }

        bool try_take(T& out) {
            int ret = sem_trywait(&_consumer_sem);
            if (ret == -1 && errno == EAGAIN) {
                return false;
            }

            pthread_mutex_lock(&_lock);
            out = _queue.front();
            _queue.pop_front();
            --_curr_size;
            if (_max_size > 0) {
                sem_post(&_producer_sem);
            }
            pthread_mutex_unlock(&_lock);
            return true;
        }

        size_t size() {
            return _curr_size;
        }
    };

  • 相关阅读:
    高阶函数之函数柯里化function currying
    学习javascript设计模式之状态模式
    学习javascript设计模式之代理模式
    学习javascript设计模式之发布-订阅(观察者)模式
    Json序列化提示缺少编译器要求的成员“ystem.Runtime.CompilerServices.ExtensionAttribute..ctor”
    获取实例
    webservice跨域问题
    IIS客户端没有权限
    IIS7.5 错误代码0x8007007e HTTP 错误 500.19
    获取当前文件夹路径
  • 原文地址:https://www.cnblogs.com/zapline/p/6742063.html
Copyright © 2011-2022 走看看