21xrx.com
2025-03-20 11:44:34 Thursday
文章检索 我的文章 写文章
C++11多线程经典案例
2023-07-11 15:27:23 深夜i     24     0
C++11 多线程 经典案例

随着计算机性能的不断提高和多核处理器的普及,多线程编程已经成为了现代软件开发的重要组成部分。然而,在多线程编程中,由于线程的并发执行和共享资源的访问,程序的正确性和性能一直是难题。为了解决这个问题,C++11引入了一系列的语言特性和库函数,为多线程编程提供了更加便捷和安全的方式。

在本文中,我们将介绍几个C++11多线程经典案例。

1. 线程同步

在多线程编程中,线程之间共享的变量和资源可能会引发竞争条件,从而导致程序出错。为了避免这种问题,我们需要使用线程同步机制来协调线程之间的计算和数据访问。

C++11提供了一个std::mutex类来实现线程互斥。我们可以使用std::lock_guard类来自动管理mutex的锁定和解锁操作,从而避免手动实现锁操作的复杂性。

例如,下面的代码演示了如何使用std::mutex和std::lock_guard来保护数据结构的读写:

#include <mutex>
#include <vector>
std::vector<int> data; // 共享数据
void add_data(int n) {
  static std::mutex mtx; // 只在第一次调用时初始化
  std::lock_guard<std::mutex> lock(mtx); // 锁定互斥量
  data.push_back(n); // 执行写操作
}
int get_data(int index) {
  static std::mutex mtx; // 只在第一次调用时初始化
  std::lock_guard<std::mutex> lock(mtx); // 锁定互斥量
  return data[index]; // 执行读操作
}

2. 原子操作

除了互斥锁之外,C++11还引入了原子类型和原子操作来保证共享变量的原子性。原子操作是一种对共享变量进行操作的原子性语句,可以保证不会发生竞争条件,从而避免了锁定互斥量的开销和死锁的问题。

C++11提供了多种原子类型和原子操作,包括std::atomic、std::atomic_flag、std::atomic_exchange等。下面是一个使用std::atomic进行原子操作的例子:

#include <atomic>
std::atomic<int> counter(0); // 原子计数器
void inc_counter() {
  counter.fetch_add(1); // 原子递增
}
int get_counter() {
  return counter.load(); // 原子读取
}

3. 条件变量

在多线程编程中,我们经常需要等待某个条件达成,然后再继续执行。C++11提供了std::condition_variable类来实现这个功能。条件变量可以让线程在等待时进入睡眠状态,并在条件满足时自动唤醒,从而避免了占用CPU资源的问题。

例如,下面的代码演示了如何使用std::condition_variable和std::unique_lock来等待线程条件达成:

#include <condition_variable>
#include <mutex>
std::mutex mtx; // 互斥量
std::condition_variable cv; // 条件变量
bool ready = false;
void wait_for_ready() {
  std::unique_lock<std::mutex> lock(mtx); // 锁定互斥量
  while (!ready) {
    cv.wait(lock); // 等待条件变量
  }
  // 条件满足,执行操作
}
void set_ready() {
  std::unique_lock<std::mutex> lock(mtx); // 锁定互斥量
  ready = true; // 设置条件
  cv.notify_all(); // 唤醒所有等待线程
}

4. 异步操作

异步操作是一种并行编程模式,可以将计算任务分离成多个独立的部分,并在多个线程上同时执行,从而提高程序的性能和响应时间。

C++11提供了std::async函数和std::future类来实现异步操作。std::async函数可以在后台启动一个线程,并返回一个std::future对象,用于检查操作的状态和获取返回值。

下面是一个使用std::async和std::future进行异步操作的例子:

#include <future>
int do_work()
  // 执行计算任务
  return 42;
void process_async() {
  std::future<int> fut = std::async(do_work); // 异步执行计算任务
  int result = fut.get(); // 等待计算任务完成并获取返回值
  // 处理返回值
}

在本文中,我们介绍了几个C++11多线程的经典案例,包括线程同步、原子操作、条件变量和异步操作。这些技术可以提高多线程程序的正确性和性能,是现代软件开发的重要组成部分。

  
  

评论区