21xrx.com
2024-06-03 00:22:26 Monday
登录
文章检索 我的文章 写文章
C++线程池设计模式:如何实现高效的多线程处理?
2023-07-09 01:02:13 深夜i     --     --
C++ 线程池 设计模式 高效 多线程处理
return stopped || !tasks.empty(); return stopped || !tasks.empty();

随着计算机硬件性能的不断提升,越来越多的应用程序开始采用多线程技术来实现高效的并行计算。随之而来的问题是如何管理和调度这些线程,以避免线程之间的竞争和死锁等问题。

C++线程池设计模式就是一种解决这个问题的方法。线程池是一组预先创建好的工作线程,这些线程可以从一个任务队列中获取任务并执行。当任务执行完毕后,线程可以再次获取任务,以继续执行。这种设计模式可以避免线程的频繁创建和销毁带来的性能开销,同时也避免了竞争和死锁等问题。

下面是一个简单的C++线程池的实现:


#include <iostream>

#include <thread>

#include <vector>

#include <queue>

#include <mutex>

#include <condition_variable>

#include <functional>

class thread_pool {

public:

  thread_pool(int num_threads) : stopped(false) {

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

      threads.emplace_back([this]{

        while (true) {

          std::function<void()> task;

          {

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

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

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

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

            tasks.pop();

          }

          task();

        }

      });

    }

  }

  ~thread_pool() {

    {

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

      stopped = true;

    }

    condition.notify_all();

    for (auto& thread : threads) {

      thread.join();

    }

  }

  template<typename T>

  void submit(T task) {

    {

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

      tasks.emplace(task);

    }

    condition.notify_one();

  }

private:

  std::vector<std::thread> threads;

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

  std::mutex mutex;

  std::condition_variable condition;

  bool stopped;

};

以上实现中,线程池包含一个由工作线程构成的容器 `threads` 和一个任务队列 `tasks`。当一个新任务提交到线程池中时,它会被放入任务队列 `tasks` 中,并通过 `condition.notify_one()` 唤醒任一等待线程。在工作线程中,线程首先通过 `condition.wait(lock, [this]{ return stopped || !tasks.empty(); });` 进入等待状态,并等待 `tasks` 非空或者 `stopped` 为真。如果当前线程池被停止(`stopped` 为真)且任务队列为空,那么线程就会退出。

使用线程池的过程非常简单,只需要在代码中创建线程池对象,然后通过 `submit()` 方法提交任务即可:


thread_pool pool(4);

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

  pool.submit([i]{

    std::cout << "Task " << i << " started\n";

    std::this_thread::sleep_for(std::chrono::seconds(1));

    std::cout << "Task " << i << " finished\n";

  });

}

以上代码将会创建一个包含 4 个工作线程的线程池,并往任务队列中提交 100 个任务。每个任务将会输出一个开始和结束标记,并且在两个标记之间间隔 1 秒钟。

通过线程池的设计模式,我们可以避免手动创建线程带来的复杂性和性能问题,实现高效的并行计算。在实际应用中,线程池还可以通过限制并发线程数、设置任务优先级等方式进行进一步的优化,以满足不同的需求。

  
  

评论区

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