21xrx.com
2025-03-28 05:44:15 Friday
文章检索 我的文章 写文章
C++11、14、17、20 多线程:从原理到线程池实战
2023-07-09 09:53:07 深夜i     103     0
C++11 C++14 C++17 C++20 多线程 原理 线程池实战
return this->stop || !this->tasks.empty();

随着计算机技术的飞速发展,多线程编程成为了面向现代应用的必备技能,而C++作为一种高性能语言,其多线程能力也在不断提升。C++11、14、17、20版本都增强了多线程相关的特性,为我们提供了更丰富的开发手段和更高效的编程体验。

首先,我们来了解一下多线程的原理。在单核CPU时代,多线程实现的原理是通过时间片轮转来模拟多个线程同时运行的效果,然而现代计算机的CPU已经由单核逐渐升级为多核,多线程就可以真正实现多个线程同时运行。多线程并发执行,可以让我们充分利用CPU的多核处理能力,提高应用程序的性能。

接着,我们来看看C++11、14、17、20版本各自新增了哪些多线程特性。C++11新增了线程库,包括std::thread类,std::mutex类和std::condition_variable类等,为我们提供了更方便的多线程编程手段。C++14引入了std::shared_mutex类,使得多个读操作同时进行,写操作则需要等待读操作全部完成后才能进行。C++17增加了std::atomic类和std::shared_lock类,分别用于原子操作和共享锁。C++20则引入了std::jthread类,它与std::thread类类似,但提供了自动资源释放功能,并且可以与协程配合使用。

最后,我们来看看多线程实战中的一个重要工具:线程池。线程池就是一个预先创建好的线程组,用于执行多个任务。它避免了重复创建线程和销毁线程的开销,能够有效地减少系统资源的浪费。我们可以使用C++11提供的std::thread和std::function来实现线程池。

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

class ThreadPool {
public:
  explicit ThreadPool(size_t thread_count)
    : stop(false) {
    for (size_t i = 0; i < thread_count; ++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(std::forward<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;
};

上述线程池实现中,enqueue函数用于将需要执行的任务添加到队列中,线程池中的线程不断从队列中获取任务并执行,直到队列为空或线程池被销毁。

总结一下,C++11、14、17、20版本均提供了丰富的多线程编程特性,为我们开发高性能、多线程应用程序提供了极大的便利。线程池则是多线程实战中的一个重要工具,可以帮助我们在多个任务之间高效地调度和利用系统资源。

  
  

评论区