1. 程式人生 > 其它 >手撕程式碼

手撕程式碼

1、阻塞佇列/執行緒安全佇列

實現:

注意問題:

  1、防止虛假喚醒的lambda表示式需要傳入this,也就是呼叫變數

  2、lambda表示式的函式體不可以使用自己寫的判斷佇列滿或者空函式

template <typename T>
class block_queue
{
public:
    block_queue(int max_size = 1000)
    {
        if (max_size <= 0)
        {
            exit(-1);
        }

        m_max_size = max_size;
        m_size 
= 0; m_array = new T[m_max_size]; m_front = -1;; m_back = -1; } block_queue(const block_queue&) = delete; ~block_queue() { std::unique_lock<std::mutex> ulk(m_mutex); if (m_array != NULL) delete[] m_array; } /* 往佇列新增元素,需要將所有使用佇列的執行緒先喚醒 當有元素push進佇列,相當於生產者生產了一個元素 若當前沒有執行緒等待條件變數,則喚醒無意義
*/ bool push(const T &item) { std::unique_lock<std::mutex> ulk(m_mutex); /* while (m_size >= m_max_size) m_cond.wait(ulk); */ m_cond.wait(ulk, [this]() { return m_size < m_max_size; }); //將新增資料放在迴圈陣列的對應位置
m_back = (m_back + 1) % m_max_size; m_array[m_back] = item; m_size++; m_cond.notify_all(); return true; } //pop時,如果當前佇列沒有元素,將會等待條件變數 bool pop(T &item) { std::unique_lock<std::mutex> ulk(m_mutex); /* //多個消費者的時候,這裡要是用while而不是if while (m_size <= 0) m_cond.wait(guard); */ m_cond.wait(ulk, [this]() { return m_size > 0; }); //取出佇列首的元素,這裡需要理解一下,使用迴圈陣列模擬的佇列 m_front = (m_front + 1) % m_max_size; item = m_array[m_front]; m_size--; m_cond.notify_all(); return true; } //返回隊首元素 bool front(T &value) { std::unique_lock<std::mutex> ulk(m_mutex); if (0 == m_size) { //ulk.unlock(); return false; } value = m_array[m_front]; m_mutex.unlock(); return true; } //返回隊尾元素 bool back(T &value) { std::unique_lock<std::mutex> ulk(m_mutex); if (0 == m_size) { //ulk.unlock(); return false; } value = m_array[m_back]; return true; } int size() { int tmp = 0; std::unique_lock<std::mutex> ulk(m_mutex); tmp = m_size; return tmp; } int max_size() { int tmp = 0; std::unique_lock<std::mutex> ulk(m_mutex); tmp = m_max_size; return tmp; } //判斷佇列是否滿了 bool full() { std::unique_lock<std::mutex> ulk(m_mutex); if (m_size >= m_max_size) { return true; } return false; } //判斷佇列是否為空 bool empty() { std::unique_lock<std::mutex> ulk(m_mutex); if (0 == m_size) { return true; } return false; } private: std::mutex m_mutex; std::condition_variable m_cond; int m_max_size; int m_size; T* m_array; int m_front; int m_back; };
View Code

本文來自部落格園,作者:Mr-xxx,轉載請註明原文連結:https://www.cnblogs.com/MrLiuZF/p/15078857.html