设为首页 加入收藏

TOP

线程池
2019-06-23 06:05:52 】 浏览:118
Tags:线程
#pragma once
#include <functional>
#include <deque>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <memory>
#include <cassert>

class ThreadPool
{
public:
  ThreadPool(const ThreadPool& other) = delete;
  ThreadPool& operator=(const ThreadPool& other) = delete;
  using Task = std::function<void()>;

  ThreadPool(size_t max_queue_size, Task cb)
    : cb_(std::move(cb)),
    max_queue_size_(max_queue_size),
    running_(false)
  {
  }

  ~ThreadPool()
  {
    if (running_)
    {
      Stop();
    }
  }

  void Start(int num_threads)
  {
    assert(threads_.empty());
    running_ = true;
    threads_.reserve(num_threads);
    for (int i = 0; i < num_threads; ++i)
    {
      threads_.emplace_back(new std::thread(&ThreadPool::Process, this));
    }

    if (num_threads == 0 && cb_)
    {
      cb_();
    }
  }

  void Stop()
  {
    {
      std::lock_guard<std::mutex> lk(mtx_);
      running_ = false;
      not_empty_cond_.notify_all();
    }

    for (auto& th : threads_)
    {
      th->join();
    }
  }

  void InputTask(Task task)
  {
    if (threads_.empty())
    {
      task();
    }
    else
    {
      std::unique_lock<std::mutex> lk(mtx_);
      while (IsFull())
      {
        not_full_cond_.wait(lk);
      }
      assert(!IsFull());

      queue_.push_back(std::move(task));
      not_empty_cond_.notify_one();
    }
  }

private:
  void Process()
  {
    if (threads_.empty())
    {
      try
      {
        if (cb_)
        {
          cb_();
        }

        while (running_)
        {
          Task task(Pop());
          if (task)
          {
            task();
          }
        }
      }
      catch (...)
      {
        // TODO
        throw;
      }
    }
  }

  Task Pop()
  {
    std::unique_lock<std::mutex> lk(mtx_);
    while (queue_.empty() && running_)
    {
      not_empty_cond_.wait(lk);
    }

    Task task;
    if (!queue_.empty())
    {
      task = queue_.front();
      queue_.pop_front();
      if (max_queue_size_ > 0)
      {
        not_full_cond_.notify_one();
      }
    }
    return task;
  }

  bool IsFull()
  {
    return max_queue_size_ > 0 && queue_.size() >= max_queue_size_;
  }

  mutable std::mutex mtx_;
  std::condition_variable not_empty_cond_;
  std::condition_variable not_full_cond_;
  Task cb_;
  std::vector<std::unique_ptr<std::thread>> threads_;
  std::deque<Task> queue_;
  size_t max_queue_size_;
  bool running_;
};
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇第十七周 - OpenCV 学习笔记 S1 -.. 下一篇C++中的类

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目