21xrx.com
2025-03-24 06:02:08 Monday
文章检索 我的文章 写文章
C++11线程池任务实现
2023-06-22 10:02:16 深夜i     15     0
线程池 C++11 任务 实现
return m_isStop || !m_tasks.empty();

C++11线程池是一种执行多个任务的机制,可以提高程序的运行效率和并发性。它通过创建一组线程来处理一组任务,从而避免了线程的频繁创建和销毁,从而提高了程序的整体性能。

在C++11中,实现线程池的最基本的方法是创建一个包含一个或多个线程的线程池类,其中每个线程可通过调用特定的任务处理函数来执行不同的任务。这个处理函数可以有多个重载版本,每个版本负责处理不同类型的任务。

实现线程池的核心是定义线程池类及其成员函数、任务队列、线程同步和处理函数。以下这个简单的例子展示了如何使用C++11线程池来实现一个带有任务队列的线程池。

#include <vector>
#include <functional>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
template<typename TaskType>
class ThreadPool
{
public:
  ThreadPool(size_t threadNum);
  ~ThreadPool();
  void submit(TaskType task);
private:
  std::vector<std::thread> m_threads;
  std::queue<std::function<void()>> m_tasks;
  std::mutex m_mutex;
  std::condition_variable m_cv;
  bool m_isStop;
};
template<typename TaskType>
ThreadPool<TaskType>::ThreadPool(size_t threadNum) : m_isStop(false)
{
  for (size_t i = 0; i < threadNum; i++)
  {
    m_threads.emplace_back(std::thread([this]() {
      while (true)
      {
        std::function<void()> task;
        {
          std::unique_lock<std::mutex> lk(m_mutex);
          m_cv.wait(lk, [this]()->bool { return m_isStop || !m_tasks.empty(); });
          if (m_isStop && m_tasks.empty())
          
            return;
          
          task = std::move(m_tasks.front());
          m_tasks.pop();
        }
        task();
      }
    }));
  }
}
template<typename TaskType>
ThreadPool<TaskType>::~ThreadPool()
{
  {
    std::unique_lock<std::mutex> lk(m_mutex);
    m_isStop = true;
  }
  m_cv.notify_all();
  for (auto& th : m_threads)
  {
    th.join();
  }
}
template<typename TaskType>
void ThreadPool<TaskType>::submit(TaskType task)
{
  std::unique_lock<std::mutex> lk(m_mutex);
  m_tasks.push(std::function<void()>(task));
  m_cv.notify_one();
}

上面的代码中,线程池类ThreadPool是一个模板类,可以根据不同的任务类型定义不同的线程池类。在构造函数中,创建了指定数量的线程,并使用lambda函数作为线程的执行函数。

在线程的执行函数中,使用while循环不断地从任务队列中取出任务并执行。取任务时使用unique_lock保护任务队列,如果队列为空,调用wait函数释放unique_lock并等待唤醒。如果唤醒原因是线程池关闭,线程就终止执行。如果唤醒原因是有新的任务可执行,就从队头取出任务,并释放unique_lock!最后执行该任务!

在submit函数中,加锁保护任务队列,并将任务压入队列中。调用notify_one函数通知线程有新的任务可以执行。

在使用线程池时,只需要定义任务函数,并通过线程池submit函数将任务提交到队列中即可。

void taskFunction(int x)
{
  std::cout << "Task " << x << " is running in thread " << std::this_thread::get_id() << std::endl;
}
int main()
{
  ThreadPool<void(int)> pool(4);
  for (int i = 0; i < 20; i++)
  {
    pool.submit(taskFunction, i);
  }
  return 0;
}

上面的代码定义了一个任务函数taskFunction,通过submit函数将任务提交到线程池中,并指定线程池大小为4。程序会顺序地输出任务执行的顺序和线程ID,表明任务在多个线程中间执行。

C++11线程池是一种高效的并行执行机制,可以最大限度地发挥CPU的计算能力。使用C++11的标准库提供的线程、锁和条件变量等机制,可以很方便地实现线程池,提高程序的运行效率和并发性,从而满足当今多线程编程的需求。

  
  

评论区