C++互斥对象std::mutex与std::shared_mutex;互斥锁:std::lock_guard、std::unique_lock与std::shared_lock的应用

总结:
1、两个常用的互斥对象:std::mutex(互斥对象),std::shared_mutex(读写互斥对象)
2、三个用于代替互斥对象的成员函数,管理互斥对象的锁(都是构造加锁,析构解锁):std::lock_guard用于管理std::mutexstd::unique_lockstd::shared_lock管理std::shared_mutex
3、以上对象用法见下。

1、std::mutex(互斥对象)
简单的信号量,不支持递归
原理: A mutex is a lockable object that is designed to signal when critical sections of code need exclusive access, preventing other threads with the same protection from executing concurrently and access the same memory locations.
用法见网站:cplusplus mutex

// mutex example
#include        // std::cout
#include          // std::thread
#include           // std::mutex

std::mutex mtx;           // mutex for critical section

void print_block (int n, char c) {
  // critical section (exclusive access to std::cout signaled by locking mtx):
  mtx.lock();
  for (int i=0; i<n; ++i) { std::cout << c; }
  std::cout << '\n';
  mtx.unlock();
}

int main ()
{
  std::thread th1 (print_block,50,'*'); // 线程传递的函数指针与参数
  std::thread th2 (print_block,50,'$');
  th1.join();
  th2.join();
  return 0;
}

2、std::lock_guard(锁保护:基于作用域的互斥体所有权包装器
原型:template class lock_guard;
原理:是管理互斥对象的对象。构造时,互斥体对象(mtx)被调用线程锁定,析构时,互斥体被解锁
用法:

std::mutex mtx;
std::lock_guard<std::mutex> lck (mtx);  // 构造时加锁,离开作用域析构解锁

在函数内部构造lck,离开作用域自动析构,因此互斥锁mtx可以在构造锁保护对象lck时加锁,离开作用域自动解锁。通过这种方式,它可以确保互斥对象在发生异常时被正确解锁,避免调用mtx.lock(),mtx.unlock();的繁琐。
用法见网站:cplusplus std::lock_guard

3、std::shared_mutex(读写锁)
3.1、原理:
shared_mutex 拥有二个访问级别:

  • 共享 (读)- 多个线程能共享同一互斥的所有权。
  • 独占性(写)- 仅一个线程能占有互斥。

若一个线程已获取独占性锁(通过 lock 、 try_lock ),则无其他线程能获取该锁(包括共享的)。 仅当任何线程均未获取独占性锁时,共享锁能被多个线程获取(通过 lock_shared 、 try_lock_shared )

解读成读写锁: 共享互斥体在能由任何数量的线程同时读共享数据,但一个线程只能在无其他线程同时读写时写同一数据

3.2、用法:
== 注:通常不直接调用 lock_shared()等成员函数,而是使用std::unique_lock与std::shared_lock管理共享锁定==。

std::shared_mutex mutex_;  //互斥对象
int value_ = 2;  
unsigned int read() const {      
	std::shared_lock<std::shared_mutex> lock(mutex_);// shared_lock共享锁
	return value_;  
}  
void write() {      
	std::unique_lock<std::shared_mutex> lock(mutex_);// unique_lock独占锁
	value_++; 
}  

详细用法见学习网址(推荐学习):cppreference std::shared_lock

4、std::unique_lock与std::shared_lock(通用互斥包装器与通用共享互斥所有权包装器)
原理:用于代替互斥对象的成员函数,管理互斥对象。该包装器离开作用域析构时自动释放锁,因此不会造成死锁问题

你可能感兴趣的:(STL实用技巧笔记)