使用mutex锁,设计一个线程安全的stack,示例如下
#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> data;
std::mutex m;
public:
threadsafe_stack()
{
}
threadsafe_stack(const threadsafe_stack& other)
{
std::lock_guard<std::mutex> lock(other.m);
data = other.data; //copy in the constructor function
}
threadsafe_stack& operator=(const threadsafe_stack& other) = delete;
void push(T new_value)
{
std::lock_guard<std::mutex> lock(m);
data.push(new_value);
}
size_t size()
{
std::lock_guard<std::mutex> lock(m);
return data.size();
}
std::shared_ptr<T> pop() //get stack top data, then pop up it
{
std::lock_guard<std::mutex> lock(m);
if (data.empty()) //check if it is empty
{
throw empty_stack(); //throw an exception
}
std::shared_ptr<T> const res(std::make_shared<T>(()));
data.pop();
return res;
}
void pop(T& value)
{
std::lock_guard<std::mutex> lock(m);
if (data.empty())
throw empty_stack();
value = ();
data.pop();
}
bool empty() const
{
std::lock_guard<std::mutex> lock(m);
return data.empty();
}
};
测试代码:
#include <chrono>
#include <iostream>
#include <thread>
#include "safeStack.hxx"
void func(threadsafe_stack<int>* dat)
{
for (int i = 0; i < 12000; i++)
{
dat->push(i);
std::this_thread::yield();
}
}
int main()
{
threadsafe_stack<int> datas;
std::thread th(func, &datas);
th.detach();
do
{
size_t sz = datas.size();
std::cout << sz << std::endl;
if (sz < 12000)
{
std::this_thread::yield();
continue;
}
break;
}while(true);
return 0;
}