21xrx.com
2024-11-05 16:25:27 Tuesday
登录
文章检索 我的文章 写文章
如何创建C++线程池
2023-07-12 17:36:55 深夜i     --     --
C++ 线程池 创建 多线程 任务分配
return !m_tasks.empty() || m_stop;

线程池是一种管理和复用线程资源的技术,它可以有效地处理多个任务并减少线程创建和销毁带来的性能开销。在C++中,我们可以使用标准库中的thread和mutex等类来实现线程池,下面是具体实现方法。

1. 定义任务类型

首先,我们需要定义线程池执行的任务类型。通常情况下,任务类型应该封装为一个可调用对象,比如一个函数、一个函数对象、一个lambda表达式等。这个可调用对象应该能够独立执行,不需要依赖于线程池。

typedef std::function Task;

2. 定义线程池类

然后,我们可以定义一个线程池类,该类封装了线程池的基本操作。线程池需要以下几个属性:任务队列、线程池状态、线程池大小等。

class ThreadPool {

public:

  ThreadPool(size_t threadCount);

  ~ThreadPool();

  void enqueue(Task task);

private:

  bool m_stop;

  std::vector m_workers;

  std::queue m_tasks;

  std::mutex m_mutex;

  std::condition_variable m_cv;

};

上述代码中,ThreadPool构造函数初始化线程池大小并创建固定数量的线程;enqueue函数将任务加入任务队列;m_stop表示线程池是否已经停止;m_workers是执行任务的线程数组;m_tasks是任务队列;m_mutex是互斥锁,用于保护任务队列;m_cv是条件变量,用于在线程池空闲时等待新任务。

3. 定义任务执行函数

接下来,我们需要定义线程池中每个线程具体的任务执行函数。这个函数要从任务队列中获取任务并执行,直到线程池被停止。

void ThreadPool::workerThread() {

  while(!m_stop) {

    Task task;

    {

      std::unique_lock lock(m_mutex);

      m_cv.wait(lock, [this]() { return !m_tasks.empty() || m_stop; });

      if(m_stop && m_tasks.empty())

        return;

      task = m_tasks.front();

      m_tasks.pop();

    }

    task();

  }

}

4. 实现线程池的构造函数和析构函数

在构造函数中,我们需要创建指定数量的worker线程,并将它们绑定到执行函数workerThread上。

ThreadPool::ThreadPool(size_t threadCount) : m_stop(false) {

  for(size_t i = 0;i < threadCount; ++i) {

    m_workers.emplace_back(std::bind(&ThreadPool::workerThread, this));

  }

}

在析构函数中,我们需要停止线程池并等待所有线程结束。

ThreadPool::~ThreadPool() {

  {

    std::unique_lock lock(m_mutex);

    m_stop = true;

  }

  m_cv.notify_all();

  for(auto& worker : m_workers) {

    worker.join();

  }

}

5. 实现任务队列管理函数

最后,我们需要实现enqueue函数,将任务加入到任务队列中。enqueue函数要先获取互斥锁,然后将任务加入到任务队列中,并通知等待的线程。

void ThreadPool::enqueue(Task task) {

  {

    std::unique_lock lock(m_mutex);

    m_tasks.push(task);

  }

  m_cv.notify_one();

}

到此,一个简单的C++线程池就实现了。线程池可以有效的管理和复用线程资源,提高了程序的性能。

  
  

评论区

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