#ifndef TOOLS__THREAD_SAFE_QUEUE_HPP #define TOOLS__THREAD_SAFE_QUEUE_HPP #include #include #include #include #include namespace tools { template class ThreadSafeQueue { public: ThreadSafeQueue( size_t max_size, std::function full_handler = [] {}) : max_size_(max_size), full_handler_(full_handler) { } void push(const T & value) { std::unique_lock lock(mutex_); if (queue_.size() >= max_size_) { if (PopWhenFull) { queue_.pop(); } else { full_handler_(); return; } } queue_.push(value); not_empty_condition_.notify_all(); } void pop(T & value) { std::unique_lock lock(mutex_); not_empty_condition_.wait(lock, [this] { return !queue_.empty(); }); if (queue_.empty()) { std::cerr << "Error: Attempt to pop from an empty queue." << std::endl; return; } value = queue_.front(); queue_.pop(); } T pop() { std::unique_lock lock(mutex_); not_empty_condition_.wait(lock, [this] { return !queue_.empty(); }); T value = std::move(queue_.front()); queue_.pop(); return std::move(value); } T front() { std::unique_lock lock(mutex_); not_empty_condition_.wait(lock, [this] { return !queue_.empty(); }); return queue_.front(); } void back(T & value) { std::unique_lock lock(mutex_); if (queue_.empty()) { std::cerr << "Error: Attempt to access the back of an empty queue." << std::endl; return; } value = queue_.back(); } bool empty() { std::unique_lock lock(mutex_); return queue_.empty(); } void clear() { std::unique_lock lock(mutex_); while (!queue_.empty()) { queue_.pop(); } not_empty_condition_.notify_all(); // 如果其他线程正在等待队列不为空,这样可以唤醒它们 } private: std::queue queue_; size_t max_size_; mutable std::mutex mutex_; std::condition_variable not_empty_condition_; std::function full_handler_; }; } // namespace tools #endif // TOOLS__THREAD_SAFE_QUEUE_HPP