21xrx.com
2024-12-27 21:02:29 Friday
登录
文章检索 我的文章 写文章
C++ 线程池代码实现
2023-06-29 10:18:28 深夜i     --     --
C++ 线程池 代码实现 并发编程 多线程编程
return this->stop || !this->tasks.empty();

C++线程池代码实现

线程池是一种用于管理多线程任务的设计模式,它可以在需要的时候创建线程,并让它们执行一定的任务。线程池的好处是可以减少线程初始化和销毁的开销,从而提高了系统的性能和可伸缩性。C++是一种高效的编程语言,而且在多线程编程方面有着显著的优势,因此,C++线程池的实现很常见。

下面是一个简单的C++线程池代码实现:


#include <iostream>

#include <thread>

#include <mutex>

#include <condition_variable>

#include <queue>

#include <functional>

class ThreadPool {

public:

  // 构造函数,接收线程池大小

  ThreadPool(size_t size) : stop(false) {

    for (size_t i = 0; i < size; ++i)

      workers.emplace_back([this] {

        for (;;) {

          std::function<void()> task;

          {

            std::unique_lock<std::mutex> lock(this->queue_mutex);

            this->condition.wait(lock,

                       [this] { return this->stop || !this->tasks.empty(); });

            if (this->stop && this->tasks.empty())

              return;

            task = std::move(this->tasks.front());

            this->tasks.pop();

          }

          task();

        }

      });

  }

  // 提交任务到线程池

  template<class Func, class... Args>

  auto enqueue(Func &&func, Args &&... args) ->std::future<typename std::result_of<Func(Args...)>::type> {

    using return_type = typename std::result_of<Func(Args...)>::type;

    auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<Func>(func),

                                         std::forward<Args>(args)...));

    std::future<return_type> res = task->get_future();

    {

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

      if (stop)

        throw std::runtime_error("enqueue on stopped ThreadPool");

      tasks.emplace([task]() { (*task)(); });

    }

    condition.notify_one();

    return res;

  }

  // 停止线程池

  ~ThreadPool() {

    {

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

      stop = true;

    }

    condition.notify_all();

    for (std::thread &worker : workers)

      worker.join();

  }

private:

  std::vector<std::thread> workers;

  std::queue<std::function<void()>> tasks;

  std::mutex queue_mutex;

  std::condition_variable condition;

  bool stop;

};

int main() {

  ThreadPool pool(4); // 创建一个包含4个线程的线程池

  std::vector<std::future<int>> results;

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

    results.emplace_back(

        pool.enqueue([i] {

          std::cout << "hello " << i << std::endl;

          std::this_thread::sleep_for(std::chrono::seconds(1));

          std::cout << "world " << i << std::endl;

          return i * i;

        })

    );

  }

  for (auto &&result : results)

    std::cout << result.get() << ' ';

  std::cout << std::endl;

  return 0;

}

在这段代码中,ThreadPool是一个线程池类,其中包含了一个构造函数、一个提交任务的enqueue函数和一个停止线程池的析构函数。workers是一个线程向量,用于存储运行的工作线程。tasks是一个任务队列,用于存储任务。queue_mutex和condition是同步机制,用于同步线程之间的通信。stop是一个布尔值,用于指示线程池是否停止。

构造函数ThreadPool(size_t size)接收线程池的大小,该函数会在创建对象时启动指定数量的工作线程。每个工作线程都会循环处理从任务队列中取出的任务,直到线程池被停止。

enqueue函数模板是用于将任务提交到任务队列中的函数,它接收一个可调用对象作为参数及其参数,返回一个std::future对象。该函数会将可调用对象包装成一个函数对象,并放入任务队列中,然后通过condition.notify_one()通知一个工作线程取出任务执行,并返回一个std::future对象以得到可调用对象的返回值。

析构函数~ThreadPool()负责停止线程池。它设置stop为true,并通知所有线程线程池已经停止。然后,它等待每个工作线程运行到结束。

在main函数中,我们创建了一个ThreadPool对象,并使用它来启动8个任务,并等待它们的完成。在这里,我们是使用lambda表达式来模拟一个任务,每个任务执行完打印一句话,并返回一个数。

这是一个简单的C++线程池代码实现。线程池是一个非常重要的设计模式,可以在处理高并发任务时提高系统的性能和可伸缩性,C++线程池的实现是一项极其重要的技术衍生。

  
  

评论区

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