21xrx.com
2024-11-22 07:19:35 Friday
登录
文章检索 我的文章 写文章
简易C++线程池库开发
2023-07-04 23:27:37 深夜i     --     --
C++ 线程池 库开发
return m_stop || !m_taskQueue.empty();

C++线程池是一种实现多线程编程的技术,它能让程序更加高效、稳定和可靠。在实际应用中,经常需要并发地执行一些任务,如果每个任务都单独启动一个线程,就可能带来过多的开销和性能问题。而线程池可以有效地解决这个问题。

本文将介绍如何使用C++语言开发一个简易的线程池库,使得开发者能够更加轻松地编写多线程程序。

1. 线程池的概念

线程池是一组可重复使用的线程集合,它能够管理多个任务的执行,从而实现任务并发执行的效果。线程池中的任务通常都是短小精悍的,执行时间比较短。线程池中的线程在完成一个任务后,并不会退出,而是等待下一个任务的到来。

2. 开发线程池库的思路

开发一个简易的C++线程池库,需要遵循以下几个基本思路:

(1)使用C++11多线程库中的标准库;

(2)使用Lambda表达式简化代码;

(3)将线程池的核心功能封装到一个类中;

(4)支持动态添加任务和销毁线程池;

(5)除了锁和条件变量之外,不使用其他的第三方库;

3. 实现线程池

首先,我们需要定义一个线程池类,包含线程池的基本参数和操作,如下:


class ThreadPool {

public:

  ThreadPool(int threadNums); // 构造函数

  ~ThreadPool(); // 析构函数

  void addTask(Task task); // 添加任务

  void stop(); // 停止线程池

private:

  std::vector<std::thread> m_threadPool; // 线程池

  std::queue<Task> m_taskQueue; // 任务队列

  std::mutex m_mutex; // 互斥锁

  std::condition_variable m_condition; // 条件变量

  bool m_stop; // 是否停止

};

其中,Task是一个function对象,表示要执行的任务内容。

在构造函数中,我们需要初始化线程池的个数,并同时启动这些线程:


ThreadPool::ThreadPool(int threadNums) : m_stop(false) {

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

    m_threadPool.emplace_back([this]() {

      while (!m_stop) {

        Task task;

        {

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

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

          if (m_stop && m_taskQueue.empty()) return;

          task = std::move(m_taskQueue.front());

          m_taskQueue.pop();

        }

        task();

      }

    });

  }

}

任务的添加操作需要先对任务队列上锁(使用unique_lock可以实现自动解锁),然后将任务添加到队列中,并通过条件变量唤醒任意一个线程来执行这个任务:


void ThreadPool::addTask(Task task) {

  {

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

    m_taskQueue.emplace(task);

  }

  m_condition.notify_one();

}

线程池的销毁操作需要让所有任务执行完成,并将停止标志设置为true。然后再通过条件变量唤醒所有线程,并join这些线程,等待它们完成执行:


ThreadPool::~ThreadPool() {

  {

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

    m_stop = true;

  }

  m_condition.notify_all();

  for (auto& thread : m_threadPool) thread.join();

}

4. 测试使用

我们可以通过以下方式来测试刚才实现的线程池:


int main() {

  ThreadPool pool(4);

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

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

    results.emplace_back(

      pool.addTask([](int id) { std::cout << "Hello " << id << std::endl; return id * id; }, i));

  }

  for (auto& result : results) {

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

  }

  std::cout << std::endl;

  return 0;

}

在测试代码中,我们首先创建一个线程池,其中包含4个线程。然后我们添加8个任务,每个任务都是一个Lambda表达式,用来输出"Hello"和任务的ID号,并返回这个ID号的平方。最后,我们使用std::future对象来获取每个任务的执行结果,并输出到屏幕上。

5. 总结

线程池是一种非常实用的多线程技术,它能够提高程序的效率和稳定性,减少系统开销和资源浪费。本文通过C++语言实现了一个简易的线程池库,展示了如何使用Lambda表达式和标准库来实现多线程编程。开发者可以参考这个实例来编写自己的线程池库,从而提高自己的编程技能和能力。

  
  

评论区

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