21xrx.com
2024-12-22 22:46:28 Sunday
登录
文章检索 我的文章 写文章
C++线程池代码实现
2023-07-01 13:14:54 深夜i     --     --
C++ 线程池 代码实现 多线程 并发编程

随着计算机硬件的不断发展,多核CPU已经越来越普遍,线程已经成为了并发编程的基本单位。在实际开发中,我们经常需要处理大量的并发请求,管理大量的线程不但不容易,而且会降低服务器性能。因此,线程池就应运而生了。

线程池就是管理一组线程的集合,它可以帮我们自动创建线程、回收线程、控制线程的数量等。下面我们就来讲解如何使用C++代码实现线程池。

1. 线程池的基本结构

线程池一般有如下几个部分:

1.1 任务队列

任务队列一般采用生产者-消费者模型,任务的生产者是主线程,将任务放入任务队列中,消费者是线程池中的工作线程,从任务队列中取出任务并执行。

1.2 工作线程

工作线程就是线程池中的线程,负责执行任务队列中的任务。

1.3 线程池管理器

线程池管理器就是控制线程池的增、减、创建、销毁等操作。

2. 实现步骤

2.1 定义任务队列

任务队列可以使用STL中的队列实现,如下所示:


#include <queue>

#include <mutex>

#include <condition_variable>

template<typename T>

class TaskQueue {

public:

  TaskQueue() {}

  ~TaskQueue() {}

  void enqueue(const T& task) {

    std::unique_lock<std::mutex> lock(m_mutex);

    m_queue.push(task);

    m_cond.notify_one();

  }

  T dequeue() {

    std::unique_lock<std::mutex> lock(m_mutex);

    while (m_queue.empty()) {

      m_cond.wait(lock);

    }

    T val = m_queue.front();

    m_queue.pop();

    return val;

  }

private:

  std::queue<T> m_queue;

  std::mutex m_mutex;

  std::condition_variable m_cond;

};

2.2 定义工作线程

工作线程需要执行任务队列中的任务,我们需要使用C++11中的std::thread来创建一个线程,如下所示:


#include <thread>

class Worker {

public:

  Worker(TaskQueue<std::function<void()>>* task_queue)

    : m_task_queue(task_queue)

  {

    std::thread([this] { run(); }).detach();

  }

  void run() {

    for (;;) {

      std::function<void()> task = m_task_queue->dequeue();

      task();

    }

  }

private:

  TaskQueue<std::function<void()>>* m_task_queue;

};

2.3 定义线程池管理器

线程池管理器需要实现线程池的增、减、创建、销毁等操作,如下所示:


#include <vector>

#include <memory>

class ThreadPool {

public:

  ThreadPool(int thread_num)

    : m_stop(false)

  {

    for (int i = 0; i < thread_num; ++i) {

      m_workers.push_back(std::make_unique<Worker>(&m_task_queue));

    }

  }

  ~ThreadPool() {

    m_stop = true;

    m_task_queue.m_cond.notify_all();

    for (auto& worker : m_workers) {

      if (worker) {

        worker->join();

      }

    }

  }

  template<typename Function, typename... Args>

  void add_task(Function&& f, Args&&... args) {

    auto task = std::bind(std::forward<Function>(f), std::forward<Args>(args)...);

    m_task_queue.enqueue(task);

  }

private:

  bool m_stop;

  TaskQueue<std::function<void()>> m_task_queue;

  std::vector<std::unique_ptr<Worker>> m_workers;

};

3. 使用实例

使用线程池非常简单,只需要创建一个ThreadPool对象,然后调用add_task方法添加任务即可。下面是一个简单的实例:


#include <iostream>

#include "thread_pool.h"

void compute(int a, int b) {

  std::cout << "a + b = " << a + b << std::endl;

}

int main() {

  ThreadPool thread_pool(4);

  for (int i = 0; i < 10; ++i) {

    thread_pool.add_task(compute, i, i + 1);

  }

  std::cin.get();

  return 0;

}

上面的代码创建了一个ThreadPool对象,其中包含4个线程,然后通过add_task方法添加10次任务,每个任务调用compute函数,输出a+b的值。

以上就是C++线程池的基本实现,读者可以自行修改实现细节,满足自己的需求。如果需要分布式部署,可以使用类似于FastFlow、TBB、OpenMP等开源并行计算工具库。

  
  
下一篇: C++库大全

评论区

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