1. 线程安全的栈容器
#include <exception>
#include <memory>
#include <mutex>
#include <stack>
struct empty_stack : std::exception {
const char *what () const throw();
};
template <typename T>
class threadsafe_stack {
private:
std::stack<T> m_data;
mutable std::mutex m_mutex;
public:
threadsafe_stack()
{
}
threadsafe_stack (const threadsafe_stack &other)
{
std::lock_guard<std::mutex> lock (m_mutex);
m_data = other.m_data;
}
threadsafe_stack &operator= (const threadsafe_stack &) = delete;
void push (T new_value)
{
std::lock_guard<std::mutex> lock (m_mutex);
m_data.push (std::move (new_value));
}
std::shared_ptr<T> pop ()
{
std::lock_guard<std::mutex> lock (m_mutex);
if (m_data.empty())
throw empty_stack();
const std::shared_ptr<T> res (std::make_shared<T> (std::move (m_data.top())));
m_data.pop();
return res;
}
void pop (T &value)
{
std::lock_guard<std::mutex> lock (m_mutex);
if (m_data.empty())
throw empty_stack();
value = std::move (m_data.top());
m_data.pop();
}
bool empty () const
{
std::lock_guard<std::mutex> lock (m_mutex);
return m_data.empty();
}
};
2. 线程安全的队列容器
采用条件变量实现。
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
template <typename T>
class threadsafe_queue {
private:
mutable std::mutex m_mutex;
std::queue<T> m_data_queue;
std::condition_variable m_data_cond;
public:
threadsafe_queue()
{
}
void push (T new_value)
{
std::lock_guard<std::mutex> lock (m_mutex);
m_data_queue.push (std::move (new_value));
m_data_cond.notify_one();
}
void wait_and_pop (T &value)
{
std::unique_lock<std::mutex> lock (m_mutex);
m_data_cond.wait (lock, [this] { return !m_data_queue.empty(); });
value = std::move (m_data_queue.front());
m_data_queue.pop();
}
std::shared_ptr<T> wait_and_pop ()
{
std::unique_lock<std::mutex> lock (m_mutex);
m_data_cond.wait (lock, [this] { return !m_data_queue.empty(); });
std::shared_ptr<T> res (std::make_shared<T> (std::move (m_data_queue.front())));
m_data_queue.pop();
return res;
}
bool try_pop (T &value)
{
std::lock_guard<std::mutex> lock (m_mutex);
if (m_data_queue.empty())
return false;
value = std::move (m_data_queue.front());
m_data_queue.pop();
return false;
}
std::shared_ptr<T> try_pop ()
{
std::lock_guard<std::mutex> lock (m_mutex);
if (m_data_queue.empty())
return std::make_shared<T>();
std::shared_ptr<T> res (std::make_shared<T> (std::move (m_data_queue.front())));
m_data_queue.pop();
return res;
}
bool empty () const
{
std::lock_guard<std::mutex> lock (m_mutex);
return m_data_queue.empty();
}
};
参考书籍:《C++并发编程实战 第2版》