用C++11实现线程池

版本一:

轮子:https://blog.csdn.net/zdarks/article/details/46994607#commentBox

下面稍微改造了一下

不明白,可以看我上一篇:https://blog.csdn.net/chicaidecaiji/article/details/112723515

  • main.cpp

#include "ThreadPool.h"
#include <iostream>

char Func(char c) {
    int cnt = 1;
    while(cnt < 10) {
        std::cout<< c<< std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(2));
        cnt++;
    }
    return c;
}

struct G{
    int operator()(){
        std::cout << "hello, go !" << std::endl;
        return 42;
    }
};

int main(int argc, char **argv) {
    try {
        ThreadPool pool(10);
        pool.start();
        auto fut1 = pool.commit(Func, 'A');
        
        std::this_thread::sleep_for(std::chrono::seconds(1));
        auto fut2 = pool.commit(Func, 'B');
        // pool.shutdown();
        auto fut3 = pool.commit(Func, 'C');
        
        auto fut4 = pool.commit(Func, 'D');
        auto fut5 = pool.commit(Func, 'E');
        // pool.start();
        auto fut6 = pool.commit(G{});

        std::cout<<"fut1.get() :"<< fut1.get()<< std::endl;
        std::cout<<"fut2.get() :"<< fut2.get()<< std::endl;
        std::cout<<"fut3.get() :"<< fut3.get()<< std::endl;
        std::cout<<"fut4.get() :"<< fut4.get()<< std::endl;
        std::cout<<"fut5.get() :"<< fut5.get()<< std::endl;
        std::cout<<"fut6.get() :"<< fut6.get()<< std::endl;
    } catch(std::exception& e){
        std::cout << "some unhappy happened... " << e.what() << std::endl;
    }
    return 0;
}
  • ThreadPool.h

#include <deque>
#include <functional>
#include <vector>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <atomic>
#include <future>
#include <queue>

class ThreadPool {
 private:
  using Task = std::function<void()>;
  std::vector<std::thread> pool;
  std::queue<Task> tasks;
  std::condition_variable cv;
  std::mutex mux;
  std::atomic_bool state;
 public:
  ThreadPool(unsigned int sz);
  ~ThreadPool();

  template<typename F, typename... Agrs>
  auto commit(F&& f, Agrs&&... args) -> std::future<decltype(f(args...))> {
    using ResType = decltype(f(args...));
    std::shared_ptr<std::packaged_task<ResType()>> task 
      = std::make_shared<std::packaged_task<ResType()>>(std::bind(f, args...));
     // = std::make_shared<std::packaged_task<ResType()>>(std::bind(std::forward<F>(f), std::forward<Agrs>(args)...));
        
    {
      std::lock_guard<std::mutex> lock(mux);
      tasks.emplace([task]() {
        (*task)();
      });
    }

    cv.notify_all();

    std::future<ResType> future = task->get_future();
    return future;
  }

  void shutdown();
  void start();
 private:
  void schedule();
  Task getOneTask();
};
  • ThreadPool.cpp

    #include "ThreadPool.h"
    #include <iostream>
    #include <chrono>
    
    ThreadPool::ThreadPool(unsigned int sz) : state(false) {
        if(!sz) sz = 1; // 至少有一个线程
        for(unsigned int i = 0; i < sz; i++) {
            pool.emplace_back(&ThreadPool::schedule, this);
        }
    }
    
    ThreadPool::~ThreadPool() {
        for(std::thread& thd : pool) {
            thd.detach();
        }
    }
    
    ThreadPool::Task ThreadPool::getOneTask() {
        std::unique_lock<std::mutex> lock(mux);
        cv.wait(lock, [&]() { return state.load() && !tasks.empty(); });
        Task task = tasks.front();
        tasks.pop();
        return task;
    }
    
    void ThreadPool::schedule() {
        while(true) {
            Task task = getOneTask();
            task();
        }
    }
    
    void ThreadPool::shutdown() {
        std::lock_guard<std::mutex> lock(mux);
        state.store(false);
    }
    
    void ThreadPool::start() {
        {
            std::lock_guard<std::mutex> lock(mux);
            state.store(true);
        }
        cv.notify_all();
    }

    版本二:

  • #include <atomic>
    #include <queue>
    #include <functional>
    #include <future>
    #include <iostream>
    #include <thread>
    #include <vector>
    
    template<typename T>
    class SafeDeque {
     public:
      SafeDeque(){};
      ~SafeDeque(){};
    
      void push(const T& t) {
        std::lock_guard<std::mutex> lock(mutex_);
        list_.push(t);
      }
    
      bool pop(T* t) {
        std::lock_guard<std::mutex> lock(mutex_);
        if (list_.empty()) {
          return false;
        }
        *t = std::move(list_.front());
        list_.pop();
        return true;
      }
    
     private:
      std::mutex mutex_;
      std::queue<T> list_;
    };
    
    class ThreadPool {
        using Type = std::function<void()>;
     public:
      explicit ThreadPool(unsigned int thread_num);
    
      template <typename F, typename... Args>
      auto AddTask(F&& f, Args&&... args)
          -> std::future<typename std::result_of<F(Args...)>::type>;
    
      ~ThreadPool();
    
     private:
      std::vector<std::thread> workers_;
      SafeDeque<Type> tasks_;
      std::atomic_bool stop_;
    };
    
    ThreadPool::ThreadPool(unsigned int thread_num) : stop_(false) {
      while (thread_num--) {
        workers_.emplace_back([&] {
          while (!stop_) {
            Type task;
            if (tasks_.pop(&task)) {
              task();
            }
          }
        });
      }
    }
    
    ThreadPool::~ThreadPool() {
      workers_.clear();
      stop_ = true;
    }
    
    template <typename F, typename... Args>
    auto ThreadPool::AddTask(F&& f, Args&&... args)
        -> std::future<typename std::result_of<F(Args...)>::type> {
      using return_type = typename std::result_of<F(Args...)>::type;
    
      auto task = std::make_shared<std::packaged_task<return_type()>>(
          std::bind(std::forward<F>(f), std::forward<Args>(args)...));
      if (stop_) {
        return std::future<return_type>();
      }
    
      tasks_.push([task] { (*task)(); });
      return task->get_future();
    }
    
    void A(int a) {
      std::cout << std::this_thread::get_id() << "    " << a << std::endl;
      std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    
    void B(int b) {
      std::cout << std::this_thread::get_id() << "    " << b << std::endl;
      std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    
    class CC {
     public:
      void C(int c) {
        std::cout << std::this_thread::get_id() << "    " << c << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
      }
    };
    
    
    int main() {
      ThreadPool pool(10);
      int a = 0;
      int b = 1000;
      int c = 2000000;
      CC cc;
      while (a < 100) {
        pool.AddTask(A, a++);
        pool.AddTask(B, b++);
        pool.AddTask(&CC::C, cc, c++);
      }
    
      getchar();
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C++11实现线程池的示例代码: ```cpp #include <iostream> #include <vector> #include <queue> #include <thread> #include <mutex> #include <condition_variable> #include <functional> class ThreadPool { public: ThreadPool(size_t num_threads) { for (size_t i = 0; i < num_threads; ++i) { threads_.emplace_back([this] { while (true) { std::unique_lock<std::mutex> lock(mutex_); condition_.wait(lock, [this] { return !tasks_.empty() || stop_; }); if (stop_ && tasks_.empty()) return; auto task = std::move(tasks_.front()); tasks_.pop(); lock.unlock(); task(); } }); } } ~ThreadPool() { { std::unique_lock<std::mutex> lock(mutex_); stop_ = true; } condition_.notify_all(); for (auto& thread : threads_) thread.join(); } template<class F> void Enqueue(F&& task) { { std::unique_lock<std::mutex> lock(mutex_); tasks_.emplace(std::forward<F>(task)); } condition_.notify_one(); } private: std::vector<std::thread> threads_; std::queue<std::function<void()>> tasks_; std::mutex mutex_; std::condition_variable condition_; bool stop_ = false; }; int main() { ThreadPool pool(4); for (int i = 0; i < 8; ++i) { pool.Enqueue([i] { std::cout << "Task " << i << " is running" << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << "Task " << i << " is done" << std::endl; }); } return 0; } ``` 此示例实现了一个线程池,其中包含一个任务队列和一组工作线程。构造函数创建指定数量的工作线程,并启动它们以侦听任务队列。Enqueue()方法用于将新任务添加到队列中。每个工作线程将从队列中获取任务并执行它。当线程池被销毁时,所有工作线程都将被停止。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值