使用C ++实现有界阻塞队列

时间:2013-12-10 07:50:56

标签: c++ thread-safety queue blockingqueue

我对线程安全的阻塞队列不太熟悉,所以我只是用Google搜索并找到了以下引用:

  1. C++ pthread blocking queue deadlock (I think)

  2. http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

  3. 所以我只是使用C ++复制并创建了Bounded Blocking Queue。我的实施有问题吗?

    // Assume all includes are there
    struct BoundedBlockingQueueTerminateException
        : virtual std::exception,
          virtual boost::exception
    {
    
    };
    
    template<typename T>
    class BoundedBlockingQueue
    {
    private:
        std::queue<T>                        q;
        boost::mutex                         mtx;
        boost::mutex::condition_variable_any cond1; // q.empty() condition
        boost::mutex::condition_variable_any cond2; // q.size() == size condition
        int                                  nblocked1;
        int                                  nblocked2;
        bool                                 stopped;
        int                                  size;
    
    public:
        BoundedBlockingQueue(int size)
            : size(size), nblocked1(0), nblocked2(0), stopped(false)
        {
            if (size < 1)
            {
                // BOOST_THROW_EXCEPTION
            }
        }
    
        ~BoundedBlockingQueue()
        {
            Stop(true);
        }
    
        bool Empty()
        {
            boost::mutex::scoped_lock lock(mtx);
            return q.empty();
        }
    
        std::size_t Size()
        {
            boost::mutex::scoped_lock lock(mtx);
            return q.size();
        }
    
        bool TryPush(const T& item)
        {
            boost::mutex::scoped_lock lock(mtx);
            if (q.size() == size)
                return false;
    
            q.push(item);
            lock.unlock();
            cond1.notify_one();
            return true;
        }
    
        void WaitPush(const T& item)
        {
            boost::mutex::scoped_lock lock(mtx);
    
            ++nblocked2;
            while (!stopped && q.size() == size)
                cond2.wait(lock);
            --nblocked2;
    
            if (stopped)
            {
                cond2.notify_all();
                BOOST_THROW_EXCEPTION(BoundedBlockingQueueTerminateException());
            }
    
            q.push(item);
            lock.unlock(mtx);
            cond1.notify_one();
        }
    
        bool TryPop(T& popped)
        {
            boost::mutex::scoped_lock lock(mtx);
            if (q.empty())
                return false;
    
            popped = q.front();
            q.pop();
            lock.unlock(mtx);
            cond2.notify_one();
            return true;
        }
    
        void WaitPop(T& popped)
        {
            boost::mutex::scoped_lock lock(mtx);
    
            ++nblocked1;
            while (!stopped && q.empty())
                cond1.wait(lock);
            --nblocked1;
    
            if (stopped)
            {
                cond1.notify_all();
                BOOST_THROW_EXCEPTION(BoundedBlockingQueueTerminateException());
            }
    
            popped = q.front();
            q.pop();
            cond2.notify_one();
        }
    
        void Stop(bool wait)
        {
            boost::mutex::scoped_lock lock(mtx);
            stopped = true;
            cond1.notify_all();
            cond2.notify_all();
    
            if (wait)
            {
                while (nblocked1)
                    cond1.wait(lock);
                while (nblcoked2)
                    cond2.wait(lock);
            }
        }
    };
    

0 个答案:

没有答案