| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #pragma once
- #include <queue>
- #include <stdio.h>
- #include <mutex>
- #include <condition_variable>
- #include <chrono>
- namespace ylib
- {
- template<typename T>
- 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<std::mutex> 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;
- }
- /// <summary>
- /// 等待弹出;wait_msec < 0 永久等待,=0 非阻塞,>0 超时毫秒
- /// </summary>
- inline bool wait_pop(T& value, int wait_msec = -1)
- {
- std::unique_lock<std::mutex> 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<std::mutex> 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;
- };
- }
|