21xrx.com
2024-12-22 22:37:33 Sunday
登录
文章检索 我的文章 写文章
C++线程池的实现
2023-07-02 17:23:33 深夜i     --     --
C++ 线程池 实现
return !tasks.empty() || stop;

C++线程池是一种用于管理线程的工具,它能够提高程序的效率和稳定性。线程池通常由一个线程池管理器、一组工作线程和任务队列组成。线程池管理器负责向任务队列中添加任务,工作线程则从任务队列中取出任务进行执行。

线程池实现的核心是任务队列。任务队列是一个先进先出(FIFO)的队列,主要用于存储需要执行的任务。当线程池中的某个工作线程完成了当前任务,就会从队列中取出下一个任务并继续执行。

C++线程池的实现需要使用一些基本的并发编程技术,其中最重要的是互斥锁(Mutex)和条件变量(Condition Variable)。互斥锁用于保护任务队列的访问,防止多个线程同时对队列进行读写操作。条件变量用于控制线程的执行顺序,当队列为空时,工作线程会进入等待状态,直到新的任务被添加到队列中。

另外,线程池的实现还需要考虑线程的创建和销毁问题。在线程池启动时,会创建一组工作线程,并将它们加入到线程池中。当线程池关闭时,需要销毁所有的工作线程,并将任务队列中尚未执行的任务删除。

下面是一个简单的C++线程池实现,包含线程池管理器、工作线程和任务队列:


#include <iostream>

#include <vector>

#include <queue>

#include <thread>

#include <mutex>

#include <condition_variable>

using namespace std;

class ThreadPool {

private:

  vector<thread> workers; // 工作线程

  queue<function<void()>> tasks; // 任务队列

  mutex mtx; // 互斥锁

  condition_variable cv; // 条件变量

  bool stop; // 线程池是否关闭

public:

  ThreadPool(int threadNum) : stop(false) {

    // 创建工作线程

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

      workers.emplace_back([this] {

        while (true) {

          function<void()> task;

          {

            unique_lock<mutex> lock(mtx);

            // 等待任务队列中有任务

            cv.wait(lock, [this] { return !tasks.empty() || stop; });

            // 线程池关闭时退出循环

            if (stop && tasks.empty()) return;

            // 取出队列中的任务

            task = move(tasks.front());

            tasks.pop();

          }

          // 执行任务

          task();

        }

      });

    }

  }

  ~ThreadPool() {

    {

      unique_lock<mutex> lock(mtx);

      stop = true;

    }

    cv.notify_all();

    for (auto& worker: workers) {

      worker.join();

    }

    // 清空任务队列

    while (!tasks.empty()) tasks.pop();

  }

  template<class F, class... Args>

  void enqueue(F&& f, Args&&... args) {

    {

      unique_lock<mutex> lock(mtx);

      // 将任务添加到队列中

      tasks.emplace(bind(forward<F>(f), forward<Args>(args)...));

    }

    cv.notify_one();

  }

};

int main() {

  // 创建线程池

  ThreadPool pool(3);

  // 往任务队列中添加任务

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

    pool.enqueue([] (int id) {

      cout << "Task " << id << " is being processed by thread " << this_thread::get_id() << endl;

    }, i);

  }

  return 0;

}

上述代码中,使用lambda表达式创建了一组工作线程,并在其中运行一个无限循环,等待从任务队列中获取任务并执行。线程池的enqueue函数用于向任务队列中添加任务,使用std::bind将函数和参数进行了绑定,因此可以支持任意函数和任意参数。

C++线程池的实现可以帮助我们避免线程创建和销毁的开销,提高程序的效率和稳定性,特别是在处理大量任务时,线程池可以显著提升程序的运行速度。

  
  

评论区

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