UNICORNLI 发表于 2017-6-3 21:24

实现多线程安全的栈和队列

本帖最后由 UNICORNLI 于 2017-6-3 22:39 编辑

这一段研究了一下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();      
      }
};
#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,{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,{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();
      }
};
      


UNICORNLI 发表于 2017-6-3 21:32

这是源文件

夙杀々冷封 发表于 2017-6-4 10:14

楼主辛苦了

UNICORNLI 发表于 2017-6-4 10:33

夙杀々冷封 发表于 2017-6-4 10:14
楼主辛苦了

自己玩自己的,没什么辛苦不辛苦啊

2909094965 发表于 2017-6-4 11:09

这个妙不懂啊,晕晕晕,不解释

UNICORNLI 发表于 2017-6-4 12:58

2909094965 发表于 2017-6-4 11:09
这个妙不懂啊,晕晕晕,不解释

我也刚刚开始研究,慢慢学,不追求速成

aqwly 发表于 2017-6-5 09:54

好东西,可以看看,先收藏了

萌鬼出没 发表于 2017-6-5 11:09

感谢分享
页: [1]
查看完整版本: 实现多线程安全的栈和队列