60 lines
1.4 KiB
C++
60 lines
1.4 KiB
C++
#ifndef CONCURRENTQUEUE_H
|
|
#define CONCURRENTQUEUE_H
|
|
|
|
#include <queue>
|
|
#include <mutex>
|
|
#include <condition_variable>
|
|
|
|
using namespace std;
|
|
|
|
template <typename T>
|
|
class ConcurrentQueue {
|
|
private:
|
|
queue<T> queue_;
|
|
mutable mutex mutex_;
|
|
condition_variable condition_;
|
|
|
|
public:
|
|
// Apparently, if you have a mutex in a class, you can't copy or assign the class to any other class.
|
|
ConcurrentQueue() = default;
|
|
ConcurrentQueue(const ConcurrentQueue&) = delete; // Prevent copying
|
|
ConcurrentQueue& operator=(const ConcurrentQueue&) = delete; // Prevent assignment
|
|
|
|
void push(T value) {
|
|
lock_guard<mutex> lock(mutex_);
|
|
queue_.push(move(value));
|
|
condition_.notify_one();
|
|
}
|
|
|
|
bool try_pop(T& value) {
|
|
lock_guard<mutex> lock(mutex_);
|
|
if (queue_.empty()) {
|
|
return false;
|
|
}
|
|
value = move(queue_.front());
|
|
queue_.pop();
|
|
return true;
|
|
}
|
|
|
|
T wait_and_pop() {
|
|
unique_lock<mutex> lock(mutex_);
|
|
condition_.wait(lock, [this] { return !queue_.empty(); });
|
|
T value = move(queue_.front());
|
|
queue_.pop();
|
|
|
|
return value;
|
|
}
|
|
|
|
bool empty() const {
|
|
lock_guard<mutex> lock(mutex_);
|
|
return queue_.empty();
|
|
}
|
|
|
|
int size() {
|
|
lock_guard<mutex> lock(mutex_);
|
|
return queue_.size();
|
|
}
|
|
};
|
|
|
|
#endif
|