21xrx.com
2024-12-22 19:34:37 Sunday
登录
文章检索 我的文章 写文章
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++中快速创建一个高效的线程池作为多线程处理的工具。线程池不仅能够有效地提高多线程效率,还能够帮助我们控制系统资源,避免对系统产生过多负担。如果你需要使用多线程处理大量任务,那么线程池将成为你的必备工具之一。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复