多线程-多线程如何避免死锁?

发布于 2017-01-23 08:57:42 字数 51 浏览 1333 评论 11

有过多线程编程经验的朋友,很多都吃过死锁的苦,如何能避免死锁,在开发中应该注意哪些问题。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

归属感 2017-10-24 19:57:36

有一个经验:最好不要嵌套使用同步方式。

同步的操作应该是个原子操作,要么没锁,要么锁。如果处于锁之中,那么结果就无法确定,很多时候就变成了死锁。嵌套使用就很难避免这种状况出现

瑾兮 2017-10-16 13:40:40

死锁的主要原因是锁嵌套,多个线程在相互等资源,根据自己的经验总结了下如何尽量避免死锁:

利用OOP技术,资源尽量封装到类中。
针对接口编程设计到资源的操作和访问都通过接口访问,接口内加锁,资源访问对外透明。
多个线程竞争性的资源,可以适当采用单件方式。
避免过多的函数嵌套。
函数内使用资源尽量使用面向对象的方式管理锁的生命周期。

瑾兮 2017-10-07 20:03:07

1.要充分考虑多个线程之间的线程调度,如下两个线程代码:
线程1:
Acquire A
acquire B
Release A
Release B

线程2:
Acquire B
Acquire A
Release B
Release A

若线程1执行完1、2两句,线程2再调度执行,或线程2执行完1、2两句,线程1再调度执行。都不会发生死锁。
而若线程1执行完Acquire A时,切换到线程2执行Acquire B,此时将发生死锁。线程1等待B,线程2等待A,而B和A将永远无法释放。
以上两种调度情况都有可能发生,所以会产生死锁。

2.函数进入时申请了锁,函数返回前,别忘记释放掉锁。
3.若在驱动程序中使用自旋锁,必须在低于或者等于DISPATCH_LEVEL的IRQL下使用,因为线程调度是在DISPATCH_LEVEL级别完成的。否则线程得不到调度,会出现死机现显。

偏爱自由 2017-09-27 05:34:53

性能要求不是非常高的时候,可以考虑LockFree 的数据结构(可以google下),这个就不会存在锁的问题.

对性能有要求的时候,前面的朋友们都进行很细心的释了.

灵芸 2017-08-11 17:57:38

有锁就会有死锁,完全避免死锁的程序很难实现。
在复杂的业务逻辑中,个人的经验、精力、能力有限,在如何可避免死锁上面花的精力多,势花在必业务上的心思就少了。
可以看下另一种线程模型:Actor。 Erlang、Scala都有实现,Java也有一个开源项目支持:http://www.oschina.net/p/jactor

偏爱自由 2017-08-04 03:36:16

要从根本上避免,就是采用简单的线程通讯模型,比如只采用消息队列方式来通讯。
在Windows平台上,采用SendMessage, PostMessage

浮生未歇 2017-06-19 12:01:58

我有一个思路,希望可以给你启发:在可能发生死锁的位置记录时间,当超过一定时间仍无法获得全部资源,则认为发生死锁。这种情况下强制释放已经占用的资源(如果已经对资源进行了处理,记得要回滚),重新申请。
这么做的好处是可以有效解决已经发生的死锁。
缺点是只有在某些特点条件下才能使用这种方式,同时这么做对性能等也会产生影响,并增加代码的复杂度。
希望我的思路对你有帮助。

灵芸 2017-06-18 16:25:06

无法完全避免死锁,其实更加实际的提问方式是,如何在特定平台和系统上去检测和定位死锁?
比如在android平台,经常会通过查看dataanrtraces.txt系统的日志信息来分析死锁问题。

清晨说ぺ晚安 2017-04-27 17:47:38

原因很多,大部分是由于锁的使用不当造成的,下面是注意事项
1. 单线程重复申请锁
2. 双线程多锁申请
3. 环形锁申请(也就是循环等待条件)

避免方式:

合理定义锁的粒度
使用多个锁时,尽量确保所有线程都按相同的顺序获取锁,从而避免死锁。

虐人心 2017-04-23 16:25:19

要避免死锁先要知道死锁的原因,在网上找到了一篇说得还行的:

操作系统中有若干进程并发执行, 它们不断申请、使用、释放系统资源,虽然系统的进

程协调、通信机构会对它们进行控制,但也可能出现若干进程都相互等待对方释放资源才能

继续运行,否则就阻塞的情况。此时,若不借助外界因素, 谁也不能释放资源, 谁也不能解

除阻塞状态。根据这样的情况,操作系统中的死锁被定义为系统中两个或者多个进程无限期

地等待永远不会发生的条件,系统处于停滞状态,这就是死锁。

产生死锁的原因主要是:

(1) 因为系统资源不足。

(2) 进程运行推进的顺序不合适。

(3) 资源分配不当等。

如果系统资源充足, 进程的资源请求都能够得到满足,死锁出现的可能性就很低, 否则

就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。

(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件, 只要系统发生死锁, 这些条件必然成立, 而只要上述条件之

一不满足,就不会发生死锁。

死锁的解除与预防:

理解了死锁的原因, 尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和

解除死锁。所以, 在系统设计、进程调度等方面注意如何不让这四个必要条件成立, 如何确

定资源的合理分配算法, 避免进程永久占据系统资源。此外, 也要防止进程在处于等待状态

的情况下占用资源。因此,对资源的分配要给予合理的规划。

转自:http://iask.sina.com.cn/b/1891920.html

虐人心 2017-02-17 06:34:30

最重要的的就是避免资源的死锁,生命周期要控制好。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文