C++ scoped_lock,unique_lock,lock_guard
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C++ scoped_lock,unique_lock,lock_guard,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2653字,纯文字阅读大概需要4分钟。
内容图文
考虑互斥量的使用,最基本的代码是:
1 #include <iostream> 2 #include <thread> 3 #include <mutex> 4 5std::mutex g_my_mutex; 6 7 std::lock_guard<std::mutex> make_lock() { 8return std::lock_guard<std::mutex>(g_my_mutex); 9} 1011void workOnResource1() { 1213for (int i = 0; i < 10000; ++i) 14 { 15 std::lock_guard<std::mutex> lk(g_my_mutex); 16 --gi; 17 } 18} 1920void workOnResource2() { 2122for (int i = 0; i < 10000; ++i) 23 { 24 auto lk = make_lock(); 25 ++gi; 26 } 27} 2829int main() { 3031 std::thread t1(workOnResource1); 32 std::thread t2(workOnResource2); 3334 t1.join(); 35 t2.join(); 3637 std::cout << "gi=" <<gi; 38 }
这在很多例子里都常见。等等,为什么第8行编译不过去?那是因为您没有在C++17下编译。std::lock_guard是禁止拷贝和移动的。C++17 granteed copy ellision允许第8行编译通过。
比较一下,第24行和第15行,哪个更简洁一些呢?
std::lock_guard还可以这样用:
void workOnResource1() { for (int i = 0; i < 10000; ++i) { g_my_mutex.lock(); std::lock_guard<std::mutex> lk(g_my_mutex, std::adopt_lock); --gi; } }
意思就是,当lk对象构造时,不去调用mutex::lock()。因为之前自己所持有的锁已经lock了一次了(g_my_mutex.lock())。adopt就是这个意思的表达,英文的含义是收养。
当lk析构时,对g_my_mutex调用mutex::unlock,这一点没有变化。
现在考虑unique_lock的用法:用于更复杂的互斥量操作上,例如:有超时时间的加锁。
#include <iostream> #include <thread> #include <mutex> // std::mutex, std::lock_guard #include <chrono> using Ms = std::chrono::milliseconds; usingnamespace std; int gi = 0; std::timed_mutex g_my_mutex; std::lock_guard<std::timed_mutex> make_lock() { return std::lock_guard<std::timed_mutex>(g_my_mutex); //绝不能分行写} void workOnResource1() { for (int i = 0; i < 10000; ++i) { auto lk = make_lock(); ++gi; } } std::unique_lock<std::timed_mutex> make_lock2() { std::unique_lock<std::timed_mutex> lk(g_my_mutex, std::defer_lock); return lk; //故意分行写} void workOnResource2() { for (int i = 0; i < 10000; ++i) { auto lk = make_lock2(); while(lk.try_lock_for(Ms(100))==false){ std::cout << "lock fail. reason timeout. now retry..."; } --gi; } } int main() { std::thread t1(workOnResource1); std::thread t2(workOnResource2); t1.join(); t2.join(); std::cout << "gi=" <<gi; }
unique_lock支持move语义,这样它就能飞出{}之外了。像极了std::unique_ptr。同样的,它也是RAII的,当析构时,调用mutex::unlock().
std::defer_lock是个全局变量,类型是std::defer_lock_t。显然,它用于函数的重载解析时,选不同的函数执行的。defer_lock的意思是,暂时不对g_my_mutex调用任何加锁动作。
为了证明,unique_lock是可以move的,可以这样:
std::unique_lock<std::timed_mutex> lk(g_my_mutex, std::defer_lock); std::unique_lock<std::timed_mutex> lk2(std::move(lk)); lk2.lock();
scoped_lock是C++17新引进的,在处理多个互斥量时,特别简单:
参考:http://en.cppreference.com/w/cpp/thread/scoped_lock
原文:https://www.cnblogs.com/thomas76/p/8608518.html
内容总结
以上是互联网集市为您收集整理的C++ scoped_lock,unique_lock,lock_guard全部内容,希望文章能够帮你解决C++ scoped_lock,unique_lock,lock_guard所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。