windows下的多线程死锁的彻底解决办法

上篇文章Windows下解决TerminateThread终止线程导致死锁问题中,曾推断方法2会带来隐患,2.1只能减少死锁,不能彻底根除死锁。


前几天的几次测试中,确实再次出现死锁,这证明2.1的推断不假。

 

为了彻底解决死锁问题,必须仔细梳理一下了。

程序:

A线程——主线程

B线程——管理线程

C、D、E...线程——工作线程

A接收到退出指令时,执行退出操作:

(1)A给B发送通知,同时等待B线程结束,随后A线程退出。

(2)B线程接收到退出消息时,分别向C、D、E等线程发送消息,并等待他们退出,随后B线程退出。

这样的模型,本身不存在问题,也很安全。但是,为了节省系统资源,C、D、E等线程是动态创建的,当他们不是很繁忙的时候,他们也会自行退出,以释放系统资源。——其实就是参考了线程池的思路,实现上,稍微简单一些。

于是,突发事件发生了!线程B给线程C发送消息之前,他做了一件事情,加锁!当线程C接收到B的退出消息时,回收资源。如果线程C比较悠闲,他也可以退出,此时是加锁并回收资源。

问题来了。当B加锁,同时等待C退出时,C在此之前刚好比较悠闲,他自己决定退出了!C自行加锁,而此前B已经加锁,那么线程B获取到锁的控制权,线程C只有等待B释放锁,而线程B则等待线程C退出,之后才释放锁。

——死锁!

 

上次说过,为了解决这个问题,可以这样处理:

if (thread_handle!=NULL)
     {
      m_lock_manager.Unlock();
      m_lock_manager.Lock();
      WaitForSingleObject(thread_handle, INFINITE);
     }

当时认为,这种方法不安全,但是基本上可以解决问题。其实,这种方法就是赌运气。这种方法是基于概率考虑的,而对于数千并发线程(http://blog.csdn.net/shanzhizi)而言,这种死锁的概率也还是很大。

 

 20100428 :

前面提到的问题,我仔细梳理了一遍,发现自己犯了一个极其严重的错误。对于加锁,管理线程B可能加锁,工作线程C也可能加锁,这会导致死锁!

所以,在A通知B退出时,B不能再使用锁了!

B此时要做的,仅仅是等待C、D、E等工作线程退出!

 

至此,问题解决

来自:http://zhanyonhu.blog.163.com/blog/static/1618604420103232595339/?suggestedreading&wumii

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值