基于C++的线程池实现

简介:线程池是一种常见的并发编程模式,可以提高程序的性能和资源利用率。本篇博客介绍了如何使用C++来实现一个简单的线程池,以便更好地利用系统资源和管理并发任务。

学习惯例,先来了解一下什么是线程池?

线程池是一种并发编程的设计模式,它可以在程序运行时创建一组预先初始化的线程,并且通过将待执行的任务分配给这些线程来提高执行效率。线程池可以帮助我们更好地管理系统资源,并实现任务的并行处理。

为什么要使用线程池(线程池的优势)

使用线程池的好处包括:

  1. 避免了线程频繁创建和销毁的开销。
  2. 控制并发线程的数量,避免系统资源被过度消耗。
  3. 提高任务的执行效率,通过复用线程来减少线程创建和上下文切换的开销。
  4. 更容易管理和调试线程的执行。

上代码(线程池的实现过程)

下面是一个简单的线程池的实现过程的示例代码,我们使用C++11提供的线程库来实现:

#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <queue>
#include <functional>

std::mutex ex_mtx;

class ThreadPool {
 public:
  explicit ThreadPool(size_t threadNum): stop(false) {
    for (size_t i = 0; i < threadNum; i++) {
      threads.emplace_back([this]{
        while(true) {
          std::function<void()> task;
          {
            std::unique_lock<std::mutex> lock(mtx);
            cv.wait(lock, [this]{ return stop || !tasks.empty(); });

            if (stop && tasks.empty()) {
              return;
            }
            task = std::move(tasks.front());
            tasks.pop();
          }
          task();
        }
      });
    }
  }

  ~ThreadPool() {
    {
      std::unique_lock<std::mutex> lock(mtx);
      stop = true;
    }
    cv.notify_all();
    for(std::thread& thread : threads) {
      thread.join();
    }
  }

  template<class F, class... Args>
  void enqueue(F&& f, Args&&... args) {
    {
      std::unique_lock<std::mutex> lock(mtx);
      auto task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
      tasks.emplace([task]{ task(); });
    }
    cv.notify_one();
  }

 private:
  std::vector<std::thread> threads;
  std::queue<std::function<void()>> tasks;
  std::mutex mtx;
  std::condition_variable cv;
  bool stop;
};

void exampleTask(int num) {
  std::lock_guard<std::mutex> lock(ex_mtx);
  std::cout<< "Task " << num << "started." << std::endl;
  std::cout << "当前线程的真实线程 ID:" << std::this_thread::get_id() << std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(1));
  std::cout<< "Task " << num << "finished." << std::endl;
}

int main() {
  ThreadPool pool(4);  // 创建一个具有4个线程的线程池
  
  // 创建五个任务并使用enqueue提交给线程池
  for (int i = 0; i < 5; i++) {
    pool.enqueue(exampleTask, i);
  }
  // 等待任务执行完成,主线程可以从这里继续工作
  std::this_thread::sleep_for(std::chrono::seconds(5));
  std::cout<< "exit process" << std::endl;
  
  return 0;
}

在上面的示例中,我们首先定义了一个 ThreadPool 类,该类包含了线程池的各种成员变量和方法。在构造函数中,我们创建了指定数量的工作线程,并通过一个无限循环来获取任务并执行。任务队列使用了一个线程安全的队列和互斥锁来实现。

enqueue 方法用于将任务添加到任务队列中,并通过条件变量来通知等待中的工作线程有任务可执行。在析构函数中,我们首先停止线程池的运行,然后通知所有的工作线程退出,并等待它们的退出。

exampleTas 方法中使用互斥锁锁住共享代码区域,使各线程互斥访问;

main 函数中,我们创建了一个线程池,并添加了8个任务到线程池中。我们通过 std::this_thread::sleep_for 方法来模拟任务的执行时间,最后等待所有任务完成。

总结

本篇博客介绍了如何使用C++来实现一个简单的线程池。线程池可以帮助我们更好地管理系统资源和处理并发任务,提高程序的性能和效率。希望通过本篇文章的介绍,您能更好地理解并应用线程池的概念和实现方法。


这是一个简单的线程池的实现示例,使用的std::thread 来创建线程池,读者也可以使用boost库或者pthread来实现。希望这篇博客对您有所帮助!如果您有任何问题,请随时提问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值