21xrx.com
2024-12-22 17:17:34 Sunday
登录
文章检索 我的文章 写文章
如何创建C++线程池
2023-06-27 12:18:50 深夜i     --     --
C++ 线程池 创建 任务 线程安全

C++线程池是一个很有用的工具,可以提高代码的性能和响应能力。它允许您管理多个并发任务,使得每个任务都能够在一个独立的线程中运行,从而提高代码的效率。在本文中,我们将探讨如何使用C++创建一个线程池。

首先,我们需要包含头文件 `#include ` ,以便能够使用C++中的线程库。然后,我们定义一个类来表示线程池,该类包含以下成员变量:

1. 向量:用于保存所有工作线程

2. 队列:用于保存所有待处理的任务

3. 互斥变量:用于保护队列,以避免多个线程同时访问它

4. 条件变量:用于通知工作线程可以开始处理任务

5. 布尔值:指示线程池是否正在运行

以下是线程池类的基本结构:


class ThreadPool {

public:

  ThreadPool();

  void addTask(std::function<void()> func);

  ~ThreadPool();

private:

  std::vector<std::thread> workerThreads;

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

  std::mutex queueMutex;

  std::condition_variable queueCondition;

  bool poolRunning;

};

然后我们可以定义类的构造函数和析构函数。构造函数应该根据需要初始化所有成员变量。在析构函数中,我们需要停止所有正在运行的线程,并将所有待处理的任务从队列中清除。


ThreadPool::ThreadPool() : poolRunning(true) {

  for (unsigned i = 0; i < std::thread::hardware_concurrency(); ++i) {

    workerThreads.push_back(std::thread([this](){

      while(true) {

        std::function<void()> task;

        {

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

          queueCondition.wait(lock, [this](){return !poolRunning || !taskQueue.empty();});

          if (!poolRunning && taskQueue.empty())

            return;

          

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

          taskQueue.pop();

        }

        task();

      }

    }));

  }

}

ThreadPool::~ThreadPool() {

  {

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

    poolRunning = false;

  }

  queueCondition.notify_all();

  for (auto& thread : workerThreads) {

    thread.join();

  }

  while (!taskQueue.empty()) {

    taskQueue.pop();

  }

}

在上面的代码中,我们使用了C++ 11标准中的条件变量,它可以使线程在“等待信号”时不需要执行忙等待操作。

接下来,我们实现 `addTask` 函数,以便能够将新任务添加到队列中。


void ThreadPool::addTask(std::function<void()> func) {

  {

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

    taskQueue.push(std::move(func));

  }

  queueCondition.notify_one();

}

在这个函数中,我们使用了互斥量 `queueMutex` 来保护任务队列,避免多个线程同时添加任务。然后,我们使用条件变量 `queueCondition` 来通知工作线程开始处理任务。

最后,我们可以在主程序中创建一个线程池,并将所有任务添加到队列中。以下是一个简单示例:


int main() {

  ThreadPool pool;

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

    pool.addTask([]() World!" << std::endl;

    );

  }

  return 0;

}

在上述示例中,我们创建了一个线程池并将10个任务添加到队列中。每个任务打印“Hello, World!”消息到控制台。由于我们创建了多个线程来处理这些任务,因此它们可以同时运行,从而提高整个程序的性能。

总之,C++线程池是一个强大的工具,可以提高代码的性能和响应能力。使用上面的代码和示例,您可以轻松地创建自己的线程池,并在您的代码中使用它。

  
  

评论区

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