21xrx.com
2025-06-10 17:36:24 Tuesday
文章检索 我的文章 写文章
C++实现线程池:教你如何创建一个高效的线程池
2023-07-14 21:22:42 深夜i     --     --
C++ 线程池 高效 创建 教学
return m_stop || !m_tasks.empty();

线程池是提高多线程效率的有效方法之一,它可以避免线程频繁创建和销毁的开销,同时可以控制线程的最大数量,防止过多的线程占用系统资源。在C++中,也可以通过简单的代码实现一个高效的线程池。

首先,在C++中实现线程池需要用到一个常用的库——C++11,它为线程和锁提供了更高效的支持。要使用C++11,需要在编译选项中添加"-std=c++11"。

接下来,我们需要定义一个Task类,用于表示线程池中的任务。

#include <functional>
class Task {
public:
  Task(std::function<void()> task) : m_task(task) {}
  void operator()() { m_task(); }
private:
  std::function<void()> m_task;
};

其中,Task类包含一个函数指针变量m_task,这个变量指向某个任务的函数。类中还定义了一个重载操作符(),它通过调用任务的函数指针来执行任务。

接下来,我们需要定义一个Threadpool类,用于线程池的初始化和运行。

class ThreadPool {
public:
  ThreadPool(size_t threadCount);
  ~ThreadPool();
  template<class F>
  void AddTask(F&& f);
private:
  std::vector<std::thread> m_threads;
  std::queue<Task> m_tasks;
  std::mutex m_mutex;
  std::condition_variable m_condition;
  bool m_stop;
};

其中,ThreadPool类包含了以下几个变量:

- m_threads:一个线程数组,用于存储线程池中的所有线程。

- m_tasks:一个任务队列,用于存储所有待执行的任务。

- m_mutex:一个互斥锁,用于保护任务队列。

- m_condition:一个条件变量,用于线程的休眠和唤醒。

- m_stop:一个bool变量,用于控制线程是否停止。

接下来就是ThreadPool类的初始化和运行代码。

ThreadPool::ThreadPool(size_t threadCount) : m_stop(false) {
  for (size_t i = 0; i < threadCount; ++i) {
    m_threads.emplace_back([this]() {
      while (true) {
        Task task;
        {
          std::unique_lock<std::mutex> lock(m_mutex);
          m_condition.wait(lock, [this]() { return m_stop || !m_tasks.empty(); });
          if (m_stop && m_tasks.empty())
            return;
          
          task = std::move(m_tasks.front());
          m_tasks.pop();
        }
        task();
      }
    });
  }
}
ThreadPool::~ThreadPool() {
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    m_stop = true;
  }
  m_condition.notify_all();
  for (auto& thread : m_threads) {
    thread.join();
  }
}

其中,ThreadPool的构造函数中首先通过循环创建线程,并且每个线程通过一个while循环来监听任务队列。如果队列中没有任务,则线程将被阻塞,等待条件变量唤醒;如果队列中有任务,则线程将任务取出并执行。

线程池的析构函数中将m_stop设置为true,并且通过条件变量通知所有线程退出while循环。最后,主线程等待所有线程结束。

最后,我们需要为线程池类添加一个AddTask函数,用于向任务队列中添加任务。

template<class F>
void ThreadPool::AddTask(F&& f) {
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    m_tasks.emplace(std::forward<F>(f));
  }
  m_condition.notify_one();
}

其中,AddTask函数通过互斥锁保护任务队列,并且添加任务后通过条件变量唤醒一个等待中的线程。

通过以上代码实现,我们可以在C++中快速创建一个高效的线程池作为多线程处理的工具。线程池不仅能够有效地提高多线程效率,还能够帮助我们控制系统资源,避免对系统产生过多负担。如果你需要使用多线程处理大量任务,那么线程池将成为你的必备工具之一。

  
  

评论区