手撕程式碼
阿新 • • 發佈:2021-07-30
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