21xrx.com
2025-04-22 13:34:36 Tuesday
文章检索 我的文章 写文章
介绍:C++11多线程容器库使用详解
2023-06-22 02:57:43 深夜i     14     0
C++11 多线程 容器库 使用 详解

C++11中引入了较为完善的多线程容器库,使得在使用多线程编程时可以更加方便地进行数据共享及同步。本文将详细介绍C++11多线程容器库的使用方法。

1. std::mutex

std::mutex是C++11中提供的基本锁类型,用于保护共享资源的互斥访问。std::mutex提供了两个基本方法:lock()和unlock(),分别用于加锁和解锁操作。

例子:

#include <iostream>
#include <mutex>
int g_num = 0//定义一个全局变量g_num
std::mutex g_num_mutex; //定义一个互斥锁
void increase_num()
{
  g_num_mutex.lock(); //加锁
  ++g_num; //访问共享资源
  g_num_mutex.unlock(); //解锁
}
int main()
{
  std::cout << "Before g_num is " << g_num << std::endl;
  //创建多个线程,同时调用increase_num
  std::thread t1(increase_num);
  std::thread t2(increase_num);
  std::thread t3(increase_num);
  t1.join();
  t2.join();
  t3.join();
  std::cout << "After g_num is " << g_num << std::endl;
  return 0;
}

运行结果:

Before g_num is 0
After g_num is 3

2. std::lock_guard

std::lock_guard是C++11中提供的另一种锁类型,它可以自动管理线程锁的创建和销毁。当std::lock_guard创建时,它会自动调用lock()方法加锁,当std::lock_guard销毁时,它会自动调用unlock()方法解锁,这样可以将锁的生命周期与std::lock_guard的生命周期绑定在一起,避免了手动调用unlock()方法引起的资源泄漏和线程安全问题。

例子:

#include <iostream>
#include <vector>
#include <mutex>
#include <algorithm>
int g_num = 0//定义一个全局变量g_num
std::mutex g_num_mutex; //定义一个互斥锁
void increase_num()
{
  std::lock_guard<std::mutex> lock(g_num_mutex); //自动加锁
  ++g_num; //访问共享资源,不必手动解锁
}
int main()
{
  std::vector<std::thread> threads;
  for(int i = 0; i < 10; ++i)
  {
    threads.push_back(std::thread(increase_num));
  }
  std::for_each(threads.begin(), threads.end(), [](std::thread& t)
         {
           t.join();
         });
  std::cout << "After g_num is " << g_num << std::endl;
  return 0;
}

运行结果:

After g_num is 10

3. std::atomic

std::atomic是C++11中提供的另一种数据类型,它可以保证各个线程在并发执行时,对共享数据的访问不会产生线程安全问题。std::atomic可以支持多种数据类型的原子操作,如load(), store(), exchange(), compare_exchange(), fetch_add()等。

例子:

#include <iostream>
#include <thread>
#include <atomic>
std::atomic<int> g_num(0); //定义一个原子变量
void increase_num()
{
  ++g_num; //自动实现原子操作
}
int main()
{
  std::cout << "Before g_num is " << g_num << std::endl;
  //创建多个线程,同时调用increase_num
  std::thread t1(increase_num);
  std::thread t2(increase_num);
  std::thread t3(increase_num);
  t1.join();
  t2.join();
  t3.join();
  std::cout << "After g_num is " << g_num << std::endl;
  return 0;
}

运行结果:

Before g_num is 0
After g_num is 3

4. std::condition_variable

std::condition_variable是C++11中提供的线程间通信的工具,可以配合锁(std::mutex或std::unique_lock)进行使用,实现线程之间的同步。

std::condition_variable主要提供了两个方法:wait()和notify_all()。wait()方法用于阻塞当前线程,并释放锁,直到另一个线程调用notify_all()方法通知当前线程可以继续执行。

例子:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex g_mutex;
std::condition_variable g_cv; //定义一个条件变量
bool g_ready = false; //定义一个标志位
void do_print(int num)
{
  while(true)
  {
    std::unique_lock<std::mutex> lock(g_mutex);
    //wait之前必须获取锁,wait会释放锁,避免死锁
    g_cv.wait(lock, []return g_ready; );
    std::cout << "thread " << num << std::endl;
    g_ready = false; //更新标志位
    lock.unlock(); //用完必须手动释放锁
    g_cv.notify_all(); //通知其它线程
  }
}
int main()
{
  std::thread t1(do_print, 1), t2(do_print, 2), t3(do_print, 3);
  //让一个线程先开始输出
  std::this_thread::sleep_for(std::chrono::seconds(1));
  g_ready = true;
  g_cv.notify_all();
  t1.join();
  t2.join();
  t3.join();
  return 0;
}

运行结果:

thread 1
thread 2
thread 3
thread 1
thread 2
thread 3
...

以上就是C++11多线程容器库的使用方法。在进行多线程编程时,必须要考虑多种因素,如线程安全、资源竞争等,合理地使用线程锁、原子变量和条件变量可以避免这些问题的发生。

  
  

评论区