queue非线程安全
大佬封装成线程安全的,接口与原<queue>一致,但无法拷贝(锁)
#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
template <typename T>
class SharedQueue
{
public:
SharedQueue();
~SharedQueue();
T &front();
void pop();
void push(const T &item);
void push(T &&item);
size_t size();
bool empty();
private:
std::deque<T> queue_;
std::mutex mutex_;
std::condition_variable cond_;
};
template <typename T>
SharedQueue<T>::SharedQueue(){};
template <typename T>
SharedQueue<T>::~SharedQueue() {}
template <typename T>
bool SharedQueue<T>::empty()
{
return size() ? false : true;
}
template <typename T>
T &SharedQueue<T>::front()
{
std::unique_lock<std::mutex> mlock(mutex_);
while (queue_.empty())
{
cond_.wait(mlock);
}
return queue_.front();
}
template <typename T>
void SharedQueue<T>::pop()
{
std::unique_lock<std::mutex> mlock(mutex_);
while (queue_.empty())
{
cond_.wait(mlock);
}
queue_.pop_front();
}
template <typename T>
void SharedQueue<T>::push(const T &item)
{
std::unique_lock<std::mutex> mlock(mutex_);
queue_.push_back(item);
mlock.unlock(); // unlock before notificiation to minimize mutex con
cond_.notify_one(); // notify one waiting thread
}
template <typename T>
void SharedQueue<T>::push(T &&item)
{
std::unique_lock<std::mutex> mlock(mutex_);
queue_.push_back(std::move(item));
mlock.unlock(); // unlock before notificiation to minimize mutex con
cond_.notify_one(); // notify one waiting thread
}
template <typename T>
size_t SharedQueue<T>::size()
{
std::unique_lock<std::mutex> mlock(mutex_);
size_t size = queue_.size();
mlock.unlock();
return size;
}
自己加了拷贝构造和移动拷贝构造,能复制和移动了。
原本不能拷贝和移动是因为锁和条件量不能拷贝和移动。在新的拷贝和移动构造方法中,queue进行拷贝和移动,锁和条件量不拷贝或移动,而是调用默认构造函数生成新的锁和条件量。在调用时应该注意。
#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
template <typename T>
class SharedQueue
{
public:
SharedQueue();
SharedQueue(SharedQueue &);
SharedQueue(const SharedQueue &);
SharedQueue(SharedQueue &&);
~SharedQueue();
T &front();
void pop();
void push(const T &item);
void push(T &&item);
size_t size();
bool empty();
private:
std::deque<T> queue_;
std::mutex mutex_;
std::condition_variable cond_;
};
template <typename T>
SharedQueue<T>::SharedQueue(){};
template <typename T>
SharedQueue<T>::~SharedQueue() {}
template <typename T>
SharedQueue<T>::SharedQueue(SharedQueue &other) : queue_(other.queue_) {}
template <typename T>
SharedQueue<T>::SharedQueue(const SharedQueue &other) : queue_(other.queue_) {}
template <typename T>
SharedQueue<T>::SharedQueue(SharedQueue &&other) : queue_(std::move(other.queue_)) {}
template <typename T>
bool SharedQueue<T>::empty()
{
return size() ? false : true;
}
template <typename T>
T &SharedQueue<T>::front()
{
std::unique_lock<std::mutex> mlock(mutex_);
while (queue_.empty())
{
cond_.wait(mlock);
}
return queue_.front();
}
template <typename T>
void SharedQueue<T>::pop()
{
std::unique_lock<std::mutex> mlock(mutex_);
while (queue_.empty())
{
cond_.wait(mlock);
}
queue_.pop_front();
}
template <typename T>
void SharedQueue<T>::push(const T &item)
{
std::unique_lock<std::mutex> mlock(mutex_);
queue_.push_back(item);
mlock.unlock(); // unlock before notificiation to minimize mutex con
cond_.notify_one(); // notify one waiting thread
}
template <typename T>
void SharedQueue<T>::push(T &&item)
{
std::unique_lock<std::mutex> mlock(mutex_);
queue_.push_back(std::move(item));
mlock.unlock(); // unlock before notificiation to minimize mutex con
cond_.notify_one(); // notify one waiting thread
}
template <typename T>
size_t SharedQueue<T>::size()
{
std::unique_lock<std::mutex> mlock(mutex_);
size_t size = queue_.size();
mlock.unlock();
return size;
}