[关闭]
@snuffles 2020-07-21T21:20:31.000000Z 字数 3298 阅读 1463

C++ 多线程 unique lock

qianlima c++


ref
https://blog.csdn.net/daaikuaichuan/article/details/71022824
https://blog.csdn.net/guotianqing/article/details/104002449?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
https://blog.csdn.net/u012507022/article/details/85909567

motivation

为了线程的同步,共享的内存在不同线程间的发生了数据交互,避免竞争,需要同步线程.
c++11提供了两种基本的锁类型,std::lock_guard,std::unique_lock,后者提供了更好的上锁解锁控制。

锁用来在多线程访问同一个资源时防止数据竞险,保证数据的一致性访问。

多线程本来就是为了提高效率和响应速度,但锁的使用又限制了多线程的并行执行,这会降低效率,但为了保证数据正确,不得不使用锁,它们就是这样纠缠。

作为效率优先的c++开发人员,很多人谈锁色变。

unique lock

A unique lock is an object that manages a mutex object with unique ownership in both states: locked and unlocked.
管理mutex锁对象,独占(没有其他的 unique_lock 对象同时拥有某个 mutex 对象的所有权)
On construction (or by move-assigning to it), the object acquires a mutex object, for whose locking and unlocking operations becomes responsible.

The object supports both states: locked and unlocked.
有两个状态
This class guarantees an unlocked status on destruction (even if not called explicitly). Therefore it is especially useful as an object with automatic duration, as it guarantees the mutex object is properly unlocked in case an exception is thrown.
析构的时候会自己unlock
( std::unique_lock 对象也能保证在其自身析构时它所管理的 Mutex 对象能够被正确地解锁(即使没有显式地调用 unlock 函数)。因此,和 lock_guard 一样,这也是一种简单而又安全的上锁和解锁方式,尤其是在程序抛出异常后先前已被上锁的 Mutex 对象可以正确进行解锁操作,极大地简化了编写与 Mutex 相关的异常处理代码。)

Note though, that the unique_lock object does not manage the lifetime of the mutex object in any way: the duration of the mutex object shall extend at least until the destruction of the unique_lock that manages it.

features

- deferred初始化,unique_lock(mutex_type& m, defer_lock_t tag) noexcept;新创建的 unique_lock 对象管理 Mutex 对象 m,但是在初始化的时候并不锁住 Mutex 对象。 m 应该是一个没有当前线程锁住的 Mutex 对象。

创建时可以不锁定(通过指定第二个参数为std::defer_lock),而在需要时再锁定
可以随时加锁解锁
作用域规则同 lock_grard,析构时自动释放锁
不可复制,可移动
条件变量需要该类型的锁作为参数(此时必须使用unique_lock)

example1: print two line

  1. // unique_lock example
  2. #include <iostream> // std::cout
  3. #include <thread> // std::thread
  4. #include <mutex> // std::mutex, std::unique_lock
  5. std::mutex mtx; // mutex for critical section
  6. void print_block (int n, char c) {
  7. // critical section (exclusive access to std::cout signaled by lifetime of lck):
  8. std::unique_lock<std::mutex> lck (mtx);
  9. for (int i=0; i<n; ++i) { std::cout << c; }
  10. std::cout << '\n';
  11. }
  12. int main ()
  13. {
  14. std::thread th1 (print_block,50,'*');
  15. std::thread th2 (print_block,50,'$');
  16. th1.join();
  17. th2.join();
  18. return 0;
  19. }

运行结果

  1. jiayao@jiayao:~/Desktop/excersize/build$ ./exercise
  2. **************************************************
  3. $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

example2 : transfer betwee accounts

  1. #include <mutex>
  2. #include <thread>
  3. #include <chrono>
  4. #include <iostream>
  5. #include <string>
  6. using namespace std;
  7. struct bank_account//银行账户
  8. {
  9. explicit bank_account(string name, int money)
  10. {
  11. sName = name;
  12. iMoney = money;
  13. }
  14. string sName;
  15. int iMoney;
  16. mutex mMutex;//账户都有一个锁mutex
  17. };
  18. void transfer( bank_account &from, bank_account &to, int amount )//这里缺少一个from==to的条件判断个人觉得
  19. {
  20. unique_lock<mutex> lock1( from.mMutex, defer_lock );//defer_lock表示延迟加锁,此处只管理mutex
  21. unique_lock<mutex> lock2( to.mMutex, defer_lock );
  22. lock( lock1, lock2 );//lock一次性锁住多个mutex防止deadlock
  23. from.iMoney -= amount;
  24. to.iMoney += amount;
  25. cout << "Transfer " << amount << " from "<< from.sName << " to " << to.sName << endl;
  26. }
  27. int main()
  28. {
  29. bank_account Account1( "User1", 100 );
  30. bank_account Account2( "User2", 50 );
  31. thread t1( [&](){ transfer( Account1, Account2, 10 ); } );//lambda表达式
  32. thread t2( [&](){ transfer( Account2, Account1, 5 ); } );
  33. t1.join();
  34. t2.join();
  35. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注