本帖最后由 UNICORNLI 于 2017-6-3 22:39 编辑
这一段研究了一下C++多线程,就拿基本的数据结构栈和队列来练手。
[C++] 纯文本查看 复制代码 //编译需要的头文件
#include <thread>
#include <mutex>
#include <stack>
#include <exception>
//待抛的empty_stack exception
struct empty_stack:std::exception
{
const char* what() const throw();
};
//这里将stack的pop和top合并为一个pop操作,并且重载了pop操作;
template<typename T>
class threadsafe_stack
{
private:
std::stack<T> data;
mutable std::mutex m;
public:
threadsafe_stack(){}
threadsafe_stack(const threadsafe_stack& other)
{
std::lock_guard<std::mutex> lock(m);
data=other.data;
}
threadsafe_stack& operator=(const threadsafe_stack&) = delete;
void push(T new_value)
{
std::lock_guard<std::mutex> lock(m);
data.push_back(new_value);
}
std::shared_ptr<T> pop()
{
std::lock_guard<std::mutex> lock(m);
if(data.empty())throw empty_stack();
std::shared_ptr<T>const res(
std::make_shared<T>(data.top()));
data.pop();
return res;
}
void pop(T& value)
{
std::lock_guard<std::mutex> lock(m);
if(data.empty()) throw empty_stack();
value = data.top();
data.top();
}
bool empty()const
{
std::lock_guard<std::mutex> lock(m);
return data.empty();
}
};
[C++] 纯文本查看 复制代码 #include <memory>
#include <condition_variable>
#include <mutex>
#include <queue>
template<typename T>
class threadsafe_queue
{
private:
mutable std::mutex mut;
std::queue<T> data_queue;
std::condition_variable data_cond;
public:
threadsafe_queue()
{}
threadsafe_queue(const threadsafe_queue& other)
{
std::lock_guard<std::mutex> lock(mut);
data_queue = other.data_queue;
}
void push(T new_value)
{
std::lock_guard<std::mutex>lock(mut);
data_queue.emplice_back(new_value);
data_cond.notify_one();
}
void wait_and_pop(T& value)
{
std::unique_lock<std::mutex> lock(mut);
data_cond.wait(lock,[this]{return !data_queue.empty();});
value = data_queue.front();
data_queue.pop();
}
std::shared_ptr<T> wait_and_pop()
{
std::unique_lock<std::mutex> lock(mut);
data_cond.wait(lock,[this]{return !data_queue.empty();});
std::shared_ptr<T> res(
std::make_shared<T>(std::move(data_queue.front())));
data_queue.pop();
return res;
}
bool try_pop(T& value)
{
std::lock_guard<std::mutex>lock(mut);
if(data_queue.empty())
return false;
value = data_queue.front();
data_queue.pop();
return true;
}
std::shared_ptr<T> try_pop()
{
std::lock_guard<std::mutex>lock(mut);
if(data_queue.empty())
return std::shared_ptr<T>();
std::shared_ptr<T> res(
std::make_shared<T>(std::move(data_queue.front())));
data_queue.pop();
return res;
}
bool empty() const
{
std::lock_guard<std::mutex> lock(mut);
return data_queue.empty();
}
};
|