线程安全提升侵入列表很慢

时间:2016-05-06 18:33:03

标签: multithreading c++11 queue mutex boost-intrusive

我使用互斥锁包装了一个提升侵入列表,使其成为线程安全的,用作生产者/消费者队列。

但是在Windows(MSVC 14)上它很慢,在分析之后,95%的时间用于空闲,主要是push()waint_and_pop()方法。

我只有1个生产者和2个生产者/消费者线程。

有什么建议可以加快速度吗?

#ifndef INTRUSIVE_CONCURRENT_QUEUE_HPP
#define INTRUSIVE_CONCURRENT_QUEUE_HPP
#include <thread>
#include <mutex>
#include <condition_variable>
#include <boost/intrusive/list.hpp>

using namespace boost::intrusive;

template<typename Data>
class intrusive_concurrent_queue
{
protected:
    list<Data, constant_time_size<false> > the_queue;
    mutable std::mutex the_mutex;
    std::condition_variable the_condition_variable;

public:
    void push(Data * data)
    {
        std::unique_lock<std::mutex> lock(the_mutex);
        the_queue.push_back(*data);
        lock.unlock();
        the_condition_variable.notify_one();
    }

    bool empty() const
    {
        std::unique_lock<std::mutex> lock(the_mutex);
        return the_queue.empty();
    }

    size_t unsafe_size() const
    {
        return the_queue.size();
    }

    size_t size() const
    {
        std::unique_lock<std::mutex> lock(the_mutex);
        return the_queue.size();
    }

    Data* try_pop()
    {
        Data* popped_ptr;
        std::unique_lock<std::mutex> lock(the_mutex);
        if(the_queue.empty())
        {
            return nullptr;
        }

        popped_ptr= & the_queue.front();
        the_queue.pop_front();
        return popped_ptr;
    }

    Data* wait_and_pop(const bool & exernal_stop = false)
    {
        Data* popped_ptr;
        std::unique_lock<std::mutex> lock(the_mutex);

        the_condition_variable.wait(lock,[&]{ return ! ( the_queue.empty() | exernal_stop ) ; });

        if ( exernal_stop){
            return nullptr;
        }

        popped_ptr=&the_queue.front();
        the_queue.pop_front();
        return popped_ptr;
    }

    intrusive_concurrent_queue<Data> & operator=(intrusive_concurrent_queue<Data>&& origin)     
        {
        this->the_queue = std::move(the_queue);
        return *this;
        }

};

#endif // !INTRUSIVE_CONCURRENT_QUEUE_HPP

1 个答案:

答案 0 :(得分:1)

尝试从方法中删除锁定,并在使用它时锁定整个数据结构。