#pragma once #include #include #include #include #include namespace ylib { template class queue { public: struct node { T value; node* next; }; public: queue() { m_first = nullptr; m_end = nullptr; m_size = 0; } ~queue() { clear(); } inline void clear() { std::unique_lock lock(m_mutex); while (m_first != nullptr) { node* temp = m_first->next; delete m_first; m_first = temp; } m_end = nullptr; m_size = 0; m_cv.notify_all(); } inline void push(const T& value, bool locked = true) { if (locked) { m_mutex.lock(); } m_size++; if (m_first == nullptr) { m_first = new node(); m_first->next = nullptr; m_first->value = value; m_end = m_first; } else { m_end->next = new node; m_end->next->next = nullptr; m_end->next->value = value; m_end = m_end->next; } if (locked) { m_mutex.unlock(); } m_cv.notify_one(); } inline bool pop(T& value, bool locked = true) { if (locked) { m_mutex.lock(); } if (m_first == nullptr) { if (locked) { m_mutex.unlock(); } return false; } m_size--; value = m_first->value; node* temp = m_first->next; delete m_first; m_first = temp; if (m_first == nullptr) m_end = nullptr; if (locked) { m_mutex.unlock(); } return true; } /// /// 等待弹出;wait_msec < 0 永久等待,=0 非阻塞,>0 超时毫秒 /// inline bool wait_pop(T& value, int wait_msec = -1) { std::unique_lock lock(m_mutex); auto has_data = [this]() { return m_first != nullptr || m_wakeup; }; if (m_first == nullptr) { if (wait_msec < 0) m_cv.wait(lock, has_data); else if (wait_msec == 0) ; else m_cv.wait_for(lock, std::chrono::milliseconds(wait_msec), has_data); } if (m_wakeup) m_wakeup = false; if (m_first == nullptr) return false; m_size--; value = m_first->value; node* temp = m_first->next; delete m_first; m_first = temp; if (m_first == nullptr) m_end = nullptr; return true; } inline void wakeup() { { std::unique_lock lock(m_mutex); m_wakeup = true; } m_cv.notify_all(); } inline size_t size() { return m_size; } node* m_first; node* m_end; std::mutex m_mutex; std::condition_variable m_cv; size_t m_size; bool m_wakeup = false; }; }