这个必然让我有点疑惑,A 等待 B,B 等待 A 这种还有意外会发生吗?求教。
1
QK8wAUi0yXBY1pT7 2018-05-23 10:53:10 +08:00
建议多翻一下《操作系统》和语文书。
|
2
zhengxiaowai 2018-05-23 10:55:21 +08:00
分分钟 100 个例子
|
3
luojianxhlxt 2018-05-23 12:09:47 +08:00
数据库里面很多,代码倒是没咋接触过
|
4
Arsenal16 2018-05-23 12:32:56 +08:00
老哥看一下 实战 Java 高并发程序设计 4.5 有关死锁的问题 那一章节
百分百死锁啊, 讲的还是挺详细的. 这里贴代码排版会有问题, 老哥你可以直接去看一下书 |
5
ldd 2018-05-23 12:57:38 +08:00
这个是肯定会引起死锁的,这种情况在多节点的 RAC 上见得比较多,比如需要同时更新多个表时,不同的业务对这几张表的更新顺序不一致,就容易引发死锁。
不过像 Oracl 这样企业级的软件都会有自动的解锁行为,有个时间阈值,超过后就会牺牲掉一个事物,达到解锁目的。所以实际业务中几乎不会出现长时间的死锁。 |
6
q397064399 2018-05-23 13:09:35 +08:00
死锁的四个必要条件
|
7
0Y89tX3MgR4I 2018-05-23 13:33:07 +08:00 via Android 6
是不是我语文不好,看不懂楼主想表达什么
|
9
GuuJiang 2018-05-23 13:43:56 +08:00
methodA() {
synchronized(lockA) { Thread.sleep(10000); synchronized(lockB) { ... } } } methodB() { synchronized(lockB) { Thread.sleep(10000); synchronized(lockA) { ... } } } 拿去不谢 |
10
1cming OP @Arsenal16 这里我刚才看了 他举的例子也并没有特别的地方 难道是我多想了?
@hxd @zhengxiaowai @ldd @0Y89tX3MgR4I 对方的原话大意是:写一个“必然”会出现死锁的一段代码,我面过很多人,他们写的都不是严格意义上的死锁,都被我挑出来很多刺。 鉴于此,我在思考是否有代码之外比如 OS 上的一些考虑? |
11
1cming OP 对方是某一线大厂资深级别的技术 leader,感觉事情并不简单,所以才会来 V 站一问,下午我会更新一下结果。
|
12
startar 2018-05-23 14:17:55 +08:00 via Android
线程 1:
锁 A 锁 B 干活 释放 B 释放 A 线程 2: 锁 B 锁 A 干活 释放 A 释放 B 这样就会死锁啊 |
13
geelaw 2018-05-23 14:27:00 +08:00 via iPhone 2
用睡眠并不会必然导致死锁,只是以非常高的概率导致而已。
一个简单的方法是这样:线程 1 把自己的 handle 存在全局变量的 1 里,然后启动线程 2 并获得其 handle,然后等待这个 handle (等线程 2 结束);线程 2 的惟一工作是等待线程 1 的 handle。很容易证明,无论怎样调度,一定会进入死锁。 在没有单进程多线程概念的操作系统(如传统 UNIX ),你需要通过进程的等待完成类似任务。 |
14
ryd994 2018-05-23 14:49:33 +08:00 via Android
非重入锁重入就是保证死锁
|
15
ryd994 2018-05-23 14:57:42 +08:00 via Android 4
多线程的话可以用信号量
1 锁 A,2 锁 B 1 给 2 发信号,2 给 1 发信号 等到收到信号,1 锁 B,2 锁 A 因为各自没有取得锁前不会发出信号,因此收到信号就可以保证死锁 信号量可以使用操作系统的信号量,也可以使用原子变量简单实现 这不是一道考锁的题,而是一道考分布式系统事件排序的题 @GuuJiang 如果因为进程调度,method B 被调度到 A 完成之后才执行呢?正常调度系统会考虑公平性,所以很难发生。但这并不是前提条件。 |
16
roychan 2018-05-23 14:58:44 +08:00
写个哲学家就餐问题不就 ok 了。。。
|
17
John60676 2018-05-23 15:02:13 +08:00
哲学家就餐 加一
|
18
0Y89tX3MgR4I 2018-05-23 15:04:12 +08:00
@ryd994 嗯,两个锁和一个条件变量就好了
|
19
nullcc 2018-05-23 15:05:39 +08:00
thread 1:
acquire(A) acquire(B) thread 2: acquire(B) acquire(A) Bomb !!! |
20
mashiro233 2018-05-23 15:27:16 +08:00 1
楼上的一些朋友回答的很好了。
调度器的运作原理对应用层来说应该是未定义的。代码中启动 A,B 两个线程,调度器可以不保证 A 在 B 之前或者之后启动,启动了也不保证每个线程能用多少 cpu 时间。 |
21
ryd994 2018-05-23 15:39:21 +08:00 via Android
|
23
zhangchioulin 2018-05-23 16:11:16 +08:00
iOS 中 OSSpinLock 优先级反转也会死锁
|
24
USNaWen 2018-05-23 16:47:22 +08:00
互斥
不可剥夺 请求和保持 循环等待 |
25
tangweihua163 2018-05-23 19:02:07 +08:00
必然死锁,一个线程内才行,连续多次试锁同一资源?多个线程就不是必然
|
26
zhengxiaowai 2018-05-23 21:37:00 +08:00
@1cming 一个很经典的案例:哲学家就餐问题
|
27
hand515 2018-05-23 22:03:26 +08:00
线程 A:
l1.lock() while(true) l2.lock() 线程 B: l2.lock() while(true) l1.lock() |
28
KIDJourney 2018-05-23 22:40:37 +08:00
l1 = lock()
l1.lock() l1.lock() 这不就死锁了。 |
29
tempdban 2018-05-23 22:55:46 +08:00 via Android
上了一课
|
30
ryd994 2018-05-24 02:52:09 +08:00 via Android 1
|
31
jedihy 2018-05-24 03:06:36 +08:00
对,这不是考 OS,这是靠分布式系统与算法
|
32
ebingtel 2018-05-24 09:11:27 +08:00
@q397064399 对头 lz 描述的情况 只满足了一个
|
33
lerosua 2018-05-27 13:23:16 +08:00
邮局寄个包裹给你, 要你身份证就能给你,但你的身份证就在包裹里~ 所以死锁了~
|