21xrx.com
2024-11-05 16:26:46 Tuesday
登录
文章检索 我的文章 写文章
介绍:C++11多线程容器库使用详解
2023-06-22 02:57:43 深夜i     --     --
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多线程容器库的使用方法。在进行多线程编程时,必须要考虑多种因素,如线程安全、资源竞争等,合理地使用线程锁、原子变量和条件变量可以避免这些问题的发生。

  
  

评论区

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