21xrx.com
2025-03-24 22:27:03 Monday
文章检索 我的文章 写文章
使用c++11的线程池实现子任务分配和处理
2023-06-28 18:00:24 深夜i     18     0
C++11 线程池 子任务 分配 处理
return this->stop || !this->tasks.empty();

在日常的编程中,我们经常需要处理大量的数据或者进行复杂的操作。这时候,如果我们使用单一的线程进行处理,往往效率会非常低下,尤其是当数据量非常大的时候。因此,我们需要使用线程池来进行任务的分配和处理。

线程池是由多个线程组成的,可以使得我们的程序可以同时处理多个任务。其中,线程池会维护一个任务队列,当有任务需要处理时,会从队列中取出一个任务交给空闲的线程去处理。这样可以使得我们的程序可以非常快速地处理大量的任务,提高了我们程序的效率。

在C++11中,提供了一套非常方便的线程池库,可以帮助我们快速地实现线程池。下面,我们来看一下具体的例子。

#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
class ThreadPool {
public:
  ThreadPool(size_t threads) : stop(false) {
    for (size_t i = 0; i < threads; ++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 F>
  void enqueue(F&& f) {
    {
      std::unique_lock<std::mutex> lock(queue_mutex);
      tasks.emplace([f] {
        f();
      });
    }
    condition.notify_one();
  }
  ~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;
};
void subtask1() {
  std::cout << "Subtask 1 is being processed.\n";
}
void subtask2() {
  std::cout << "Subtask 2 is being processed.\n";
}
void subtask3() {
  std::cout << "Subtask 3 is being processed.\n";
}
int main()
{
  ThreadPool pool(4);
  // Add subtasks to the queue
  for (int i = 0; i < 10; i++) {
    pool.enqueue(subtask1);
    pool.enqueue(subtask2);
    pool.enqueue(subtask3);
  }
  // Wait for all tasks to be completed
  std::this_thread::sleep_for(std::chrono::seconds(1));
  return 0;
}

在这个例子中,我们首先定义了一个ThreadPool类。在它的构造函数中,我们通过std::thread来创建指定数量的线程。然后,我们定义了一个enqueue()方法,这个方法可以将一个函数放到任务队列中,准备被线程池中的某个线程处理。在enqueue()方法中,我们首先通过std::unique_lock 来上锁,然后将需要执行的函数放到任务队列中,并触发condition变量,告诉线程池中的线程有新的任务需要处理。在ThreadPool类的析构函数中,我们会等待所有线程完成自己所分配的任务,然后再关闭线程。

下面是一个示例,展示了如何将一些子任务加入到任务队列中,并且等待所有任务完成:

ThreadPool pool(4);
// Add subtasks to the queue
for (int i = 0; i < 10; i++) {
  pool.enqueue(subtask1);
  pool.enqueue(subtask2);
  pool.enqueue(subtask3);
}
// Wait for all tasks to be completed
std::this_thread::sleep_for(std::chrono::seconds(1));

通过线程池,我们可以将一些原本需要顺序执行的子任务分配给多个线程,让多个线程同时处理任务,从而提高程序的效率。总的来说,使用C++11的线程池来实现子任务分配和处理非常方便,而且能够有效地提高程序的性能。

  
  

评论区