注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

C++11及BOOST特性之三十一C++11多线程之std::lock  

2016-10-09 09:47:04|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
C++11及BOOST特性之三十一C++11多线程之std::lock

今天在看std::unique_lock的使用时,发现他前面搞了一个这个动作,以前竟然没注意:
std::mutex foo,bar;

void task_a () {
  std::lock (foo,bar);         // simultaneous lock (prevents deadlock)
  std::unique_lock<std::mutex> lck1 (foo,std::adopt_lock);
  std::unique_lock<std::mutex> lck2 (bar,std::adopt_lock);
  std::cout << "task a\n";
  // (unlocked automatically on destruction of lck1 and lck2)
}
光看名字和注释也可以明白这个lock是保证不死锁的玩儿意,但是具体的是啥还是不明白,还得查帮助。在C++11 Reference上可以查到 这个函数:
function template
<mutex>
std::lock
template <class Mutex1, class Mutex2, class... Mutexes>
  void lock (Mutex1& a, Mutex2& b, Mutexes&... cde);
Lock multiple mutexes
Locks all the objects passed as arguments, blocking the calling thread if necessary.

The function locks the objects using an unspecified sequence of calls to their members lock, try_lock and unlock that ensures that all arguments are locked on return (without producing any deadlocks).

If the function cannot lock all objects (such as because one of its internal calls threw an exception), the function first unlocks all objects it successfully locked (if any) before failing.
这东西其实就是告诉你,他会按照模板内提供的锁的对象的顺序来操作锁,防止死锁。正如网友的说明,它肯定是用类似于try_lock之类的去锁循环的下一个对象,如果无法锁到就暂停一下,而不真正的去锁住。直到能锁住为止。
看Reference上的代码:
// std::lock example
#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex, std::lock

std::mutex foo,bar;

void task_a () {
  // foo.lock(); bar.lock(); // replaced by:
  std::lock (foo,bar);
  std::cout << "task a\n";
  foo.unlock();
  bar.unlock();
}

void task_b () {
  // bar.lock(); foo.lock(); // replaced by:
  std::lock (bar,foo);
  std::cout << "task b\n";
  bar.unlock();
  foo.unlock();
}

int main ()
{
  std::thread th1 (task_a);
  std::thread th2 (task_b);

  th1.join();
  th2.join();

  return 0;
}
这个在理论是会死锁的,但实际测试了好多把都不死锁,哈哈,最后在当中加一个Sleep()才算死锁上了。所以说死锁这事儿最难弄的原因就在于它不确定性。不是必然会死锁。
http://www.cplusplus.com/reference/mutex/lock/?kw=lock
http://blog.csdn.net/nirendao/article/details/50890521
http://lib.csdn.net/article/cplusplus/29761
http://www.cnblogs.com/haippy/p/3346477.html
今天又遇到了原来的问题,在调试程序时,没有NEW对象,操作函数是没有问题的,但是一返回对象的值就崩溃了。怀疑是加锁的原因,结果被误导了,其实就是没有形成完整的对象,如果直接返回一个具体的数或者静态成员,也不崩溃。但只要操作内部成员就需要分配空间,而你没有分配空间,所以直接就崩溃了。
原因很简单,以前也说过,函数的地址是公用的,C++的编译器为了保证适用性,做了这个妥协,觉得也是正常的。所以对指针进行防御性编程或者采用智能指针还是非常必要和重要的。

  评论这张
 
阅读(40)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017