diff --git a/util/include/util/tc_thread_queue.h b/util/include/util/tc_thread_queue.h index 5eef16f..a2441fc 100644 --- a/util/include/util/tc_thread_queue.h +++ b/util/include/util/tc_thread_queue.h @@ -42,7 +42,7 @@ template > class TC_ThreadQueue { public: - TC_ThreadQueue():_size(0), _bTerminate(false){}; + TC_ThreadQueue() : _size(0){} public: @@ -139,17 +139,15 @@ public: */ bool empty() const; - /** - * @brief 调用后, 所有正在进行的、将要进行的阻塞等待将立即返回. - */ - void terminate(); - protected: TC_ThreadQueue(const TC_ThreadQueue&) = delete; TC_ThreadQueue(TC_ThreadQueue&&) = delete; TC_ThreadQueue& operator=(const TC_ThreadQueue&) = delete; TC_ThreadQueue& operator=(TC_ThreadQueue&&) = delete; + bool hasNotify(size_t lockId) const { + return lockId != _lockId; + } protected: /** * 队列 @@ -166,9 +164,9 @@ protected: //锁 mutable std::mutex _mutex; - - //结束工作否,若为true则所有的阻塞等待都将立即返回 - bool _bTerminate; + + //lockId, 判断请求是否唤醒过 + size_t _lockId = 0; }; template T TC_ThreadQueue::front() @@ -182,19 +180,21 @@ template bool TC_ThreadQueue::pop_front(T& t, size { if(wait) { + size_t lockId = _lockId; + std::unique_lock lock(_mutex); - // 此处等待两个条件: 1.来数据了; 2.terminate. + // 此处等待两个条件: 1.来数据了; 2.有人唤醒了. // 任一条件满足都将打破等待立即返回 if (millsecond == (size_t) -1) { - _cond.wait(lock, [this] { return !_queue.empty() || _bTerminate; }); + _cond.wait(lock, [&] { return !_queue.empty() || hasNotify(lockId); }); } else if (millsecond > 0) { - _cond.wait_for(lock, std::chrono::milliseconds(millsecond), [this] { return !_queue.empty() || _bTerminate; }); + _cond.wait_for(lock, std::chrono::milliseconds(millsecond), [&] { return !_queue.empty() || hasNotify(lockId); }); } - // 超时了数据还没到 或 还没超时就被terminate打破了, 直接返回 - if (_queue.empty() || _bTerminate) { + // 超时了数据还没到 或 还没超时就被notify打破了, 直接返回 + if (_queue.empty() || hasNotify(lockId)) { return false; } @@ -241,6 +241,7 @@ template bool TC_ThreadQueue::pop_front() template void TC_ThreadQueue::notifyT() { std::unique_lock lock(_mutex); + ++_lockId; _cond.notify_all(); } @@ -345,19 +346,22 @@ template void TC_ThreadQueue::push_front(const que template bool TC_ThreadQueue::swap(queue_type &q, size_t millsecond, bool wait) { if(wait) { + + size_t lockId = _lockId; + std::unique_lock lock(_mutex); - // 此处等待两个条件: 1.来数据了; 2.terminate. + // 此处等待两个条件: 1.来数据了; 2.notify来了 // 任一条件满足都将打破等待立即返回 if (millsecond == (size_t) -1) { - _cond.wait(lock, [this] { return !_queue.empty() || _bTerminate; }); + _cond.wait(lock, [&] { return !_queue.empty() || hasNotify(lockId); }); } else if (millsecond > 0) { - _cond.wait_for(lock, std::chrono::milliseconds(millsecond), [this] { return !_queue.empty() || _bTerminate; }); + _cond.wait_for(lock, std::chrono::milliseconds(millsecond), [&] { return !_queue.empty() || hasNotify(lockId); }); } - // 超时了数据还没到 或 还没超时就被terminate打破了, 直接返回 - if (_queue.empty() || _bTerminate) { + // 超时了数据还没到 或 还没超时就被notify唤醒了, 直接返回 + if (_queue.empty() || hasNotify(lockId)) { return false; } @@ -401,12 +405,6 @@ template bool TC_ThreadQueue::empty() const return _queue.empty(); } -template void TC_ThreadQueue::terminate() { - std::lock_guard lock(_mutex); - _bTerminate = true; - _cond.notify_all(); -} - } #endif