(Original) C ++ synchronous queue (original) C ++ synchronous queue

(Original) C ++ synchronous queue

Synchronous queue as a thread-safe area of ​​data sharing, data read often used between threads, such as semi-synchronous, semi-synchronous asynchronous queue thread pool.

It is actually relatively simple to use list, locks and condition variables, condition variable action is to wait for notification in the queue is full or empty time. Look at a simple synchronization queue:

 
#include <thread>
#include <condition_variable>
#include <mutex>
#include <list>
#include <iostream>
using namespace std;

template<typename T>
class SimpleSyncQueue
{
public:
    void Put(const T& x)
    {
        std::lock_guard<std::mutex> locker(m_mutex);
        m_queue.push_back(x);
        m_notEmpty.notify_one();
    }

    void Take(T& x)
    {
        std::unique_lock<std::mutex> locker(m_mutex);
        m_notEmpty.wait(locker, [this]{return !m_queue.empty();});
        x = m_queue.front();
        m_queue.pop_front();
    }

private:
    std::list<T> m_queue;
    std::mutex m_mutex;
    std::condition_variable_any m_notEmpty;
};
 


Look synchronous queue with a ceiling:

 





        
        if (m_needStop)
            return;
        list = std::move(m_queue);
        m_notFull.notify_one();
    }

    void Take(T& t)
    {
        std::unique_lock<std::mutex> locker(m_mutex);
        m_notEmpty.wait(locker, [this]{return m_needStop || NotEmpty(); });
        
        if (m_needStop)
            return;
        t = m_queue.front();
        m_queue.pop_front();
        m_notFull.notify_one();
    }

    void Stop()
    {
        {
            std::lock_guard<std::mutex> locker(m_mutex);
            m_needStop = true;
        }
        m_notFull.notify_all();
        m_notEmpty.notify_all();
    }

    bool Empty()
    {
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.empty();
    }

    bool Full()
    {
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.size() == m_maxSize;
    }

    size_t Size()
    {
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.size();
    }

    int Count()
    {
        return m_queue.size();
    }
private:
    bool NotFull() const
    {
        bool full = m_queue.size() >= m_maxSize;
        if (full)
            cout << "full, waiting,thread id: " << this_thread::get_id() << endl;
        return !full;
    }

    bool NotEmpty() const
    {
        bool empty = m_queue.empty();
        if (empty)
            cout << "empty,waiting,thread id: " << this_thread::get_id() << endl;
        return !empty;
    }

    template<typename F>
    void Add(F&&x)
    {
        std::unique_lock< std::mutex> locker(m_mutex);
        m_notFull.wait(locker, [this]{return m_needStop || NotFull(); });
            return;
        if (m_needStop)

        m_queue.push_back (STD :: Forward <F.> (X));
        m_notEmpty.notify_one (); 
    } 

Private: 
    STD :: List <T> m_queue; // buffer 
    std :: mutex m_mutex; // mutex and condition variables in combination 
    std :: condition_variable m_notEmpty; // not empty the condition variable 
    std :: condition_variable m_notFull; // not full condition variable 
    int m_maxSize; // synchronization maximum queue size 

    BOOL m_needStop; // stop sign 
};
 

 

Test code is relatively simple, I do not write. The actual application will be used later in the thread pool.

A little dream: to do its force, so that the c ++ world a better place!

Synchronous queue as a thread-safe area of ​​data sharing, data read often used between threads, such as semi-synchronous, semi-synchronous asynchronous queue thread pool.

It is actually relatively simple to use list, locks and condition variables, condition variable action is to wait for notification in the queue is full or empty time. Look at a simple synchronization queue:

 
#include <thread>
#include <condition_variable>
#include <mutex>
#include <list>
#include <iostream>
using namespace std;

template<typename T>
class SimpleSyncQueue
{
public:
    void Put(const T& x)
    {
        std::lock_guard<std::mutex> locker(m_mutex);
        m_queue.push_back(x);
        m_notEmpty.notify_one();
    }

    void Take(T& x)
    {
        std::unique_lock<std::mutex> locker(m_mutex);
        m_notEmpty.wait(locker, [this]{return !m_queue.empty();});
        x = m_queue.front();
        m_queue.pop_front();
    }

private:
    std::list<T> m_queue;
    std::mutex m_mutex;
    std::condition_variable_any m_notEmpty;
};
 


Look synchronous queue with a ceiling:

 





        
        if (m_needStop)
            return;
        list = std::move(m_queue);
        m_notFull.notify_one();
    }

    void Take(T& t)
    {
        std::unique_lock<std::mutex> locker(m_mutex);
        m_notEmpty.wait(locker, [this]{return m_needStop || NotEmpty(); });
        
        if (m_needStop)
            return;
        t = m_queue.front();
        m_queue.pop_front();
        m_notFull.notify_one();
    }

    void Stop()
    {
        {
            std::lock_guard<std::mutex> locker(m_mutex);
            m_needStop = true;
        }
        m_notFull.notify_all();
        m_notEmpty.notify_all();
    }

    bool Empty()
    {
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.empty();
    }

    bool Full()
    {
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.size() == m_maxSize;
    }

    size_t Size()
    {
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.size();
    }

    int Count()
    {
        return m_queue.size();
    }
private:
    bool NotFull() const
    {
        bool full = m_queue.size() >= m_maxSize;
        if (full)
            cout << "full, waiting,thread id: " << this_thread::get_id() << endl;
        return !full;
    }

    bool NotEmpty() const
    {
        bool empty = m_queue.empty();
        if (empty)
            cout << "empty,waiting,thread id: " << this_thread::get_id() << endl;
        return !empty;
    }

    template<typename F>
    void Add(F&&x)
    {
        std::unique_lock< std::mutex> locker(m_mutex);
        m_notFull.wait(locker, [this]{return m_needStop || NotFull(); });
            return;
        if (m_needStop)

        m_queue.push_back (STD :: Forward <F.> (X));
        m_notEmpty.notify_one (); 
    } 

Private: 
    STD :: List <T> m_queue; // buffer 
    std :: mutex m_mutex; // mutex and condition variables in combination 
    std :: condition_variable m_notEmpty; // not empty the condition variable 
    std :: condition_variable m_notFull; // not full condition variable 
    int m_maxSize; // synchronization maximum queue size 

    BOOL m_needStop; // stop sign 
};
 

 

Test code is relatively simple, I do not write. The actual application will be used later in the thread pool.

Guess you like

Origin www.cnblogs.com/leijiangtao/p/12076607.html