C++11多线程编程(三)——lock_guard和unique_lock
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C++11多线程编程(三)——lock_guard和unique_lock,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2176字,纯文字阅读大概需要4分钟。
内容图文
![C++11多线程编程(三)——lock_guard和unique_lock](/upload/InfoBanner/zyjiaocheng/616/0d4c7d4dcd614c31a7cd0bc9c79fdd69.jpg)
如果熟悉C++多线程的童鞋可能有了解到实现的互斥锁的机制还有这个写法
lock_guard<mutex> guard(mt);
那么这句话是什么意思呢?为什么又要搞个这样的写法呢?
这个也是构造互斥锁的写法,就是会在lock_guard构造函数里加锁,在析构函数里解锁,之所以搞了这个写法,C++委员会的解释是防止使用mutex加锁解锁的时候,忘记解锁unlock了。
#include <iostream> #include <thread> #include <string> #include <mutex> using namespace std; mutex mt; void thread_task() { for (int i = 0; i < 10; i++) { lock_guard<mutex> guard(mt); cout << "print thread: " << i << endl; } } int main() { thread t(thread_task); for (int i = 0; i > -10; i--) { lock_guard<mutex> guard(mt); cout << "print main: " << i << endl; } t.join(); return 0; }
这里说析构函数里解锁,那么到底什么时候调用析构函数呢?构造函数加锁我们好理解,写下这个语句的时候调用lock_guard<mutex> guard(mt),那么调用析构函数应该是大括号{}结束的时候,也就是说定义lock_guard的时候调用构造函数加锁,大括号解锁的时候调用析构函数解锁。
虽然lock_guard挺好用的,但是有个很大的缺陷,在定义lock_guard的地方会调用构造函数加锁,在离开定义域的话lock_guard就会被销毁,调用析构函数解锁。这就产生了一个问题,如果这个定义域范围很大的话,那么锁的粒度就很大,很大程序上会影响效率。
所以为了解决lock_guard锁的粒度过大的原因,unique_lock就出现了。
unique_lock<mutex> unique(mt);
这个会在构造函数加锁,然后可以利用unique.unlock()来解锁,所以当你觉得锁的粒度太多的时候,可以利用这个来解锁,而析构的时候会判断当前锁的状态来决定是否解锁,如果当前状态已经是解锁状态了,那么就不会再次解锁,而如果当前状态是加锁状态,就会自动调用unique.unlock()来解锁。而lock_guard在析构的时候一定会解锁,也没有中途解锁的功能。
当然,方便肯定是有代价的,unique_lock内部会维护一个锁的状态,所以在效率上肯定会比lock_guard慢。
所以,以上两种加锁解锁的方法,加上前面文章介绍的mutex方法,具体该使用哪一个,要依照具体的业务需求来决定,当然mt.lock()和mt.unlock()不管是哪种情况,是肯定都可以使用的。
对我而言,总感觉这个lock_guard有点鸡肋而已,完全可以用mutex来替代,忘记解锁的话一般都可以通过调试发现,而且一般情况下都不会忘记。仅仅只是因为怕忘记解锁这个原因的话,真的感觉有点多此一举,徒增学习成本罢了。
当然也许C++委员会有他们自己的考虑,对于我们而言,也只能记住就是了。
更多精彩内容,请关注同名公众:一点笔记alittle
内容总结
以上是互联网集市为您收集整理的C++11多线程编程(三)——lock_guard和unique_lock全部内容,希望文章能够帮你解决C++11多线程编程(三)——lock_guard和unique_lock所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。