如何更好地解释"僵局"?

ale*_*pro 30 concurrency multithreading deadlock concurrent-programming

我正在努力用简单的词语解释线程中的"死锁",所以请帮忙.什么可能是"死锁"(例如,在Java中)的最佳示例,以及它如何在步骤中发生以及如何防止它?但是没有深入细节.我知道这就像问两个相反的事情,但仍然.如果您有任何以前的并发编程培训经验 - 那将是一流的!

Guf*_*ffa 102

杰克和吉尔碰巧想同时做一个三明治.两者都需要一片面包,所以他们都去拿一条面包和一把刀.

杰克先拿到了刀,而吉尔先拿了一条面包.现在杰克试图找到一条面包,而吉尔试图找到这把刀,但两人都发现他们完成任务所需的东西已经在使用.如果他们都决定等到他们需要的东西不再使用,他们将永远等待彼此.僵局.

  • +1我从未听说过的关于锁的最简单的描述。 (2认同)

R S*_*hko 12

最简单的方法是让两个不同的线程尝试以不同的顺序获得两个锁:

thread 1:
lock(a)
lock(b)

thread2:
lock(b)
lock(a)
Run Code Online (Sandbox Code Playgroud)

假设线程1获得锁定A然后进入休眠状态.线程2获得锁B然后尝试获得锁A; 由于采用了锁A,线程2将被置于休眠状态,直到线程A被解锁.现在线程1回醒并试图获得锁定B并将进入休眠状态.

在这种情况下,有几种方法可以防止它:

  1. 线程永远不需要同时保持两个锁.
  2. 如果必须同时保持两个锁,则必须始终以相同的顺序获取它们(因此在上面的示例中,需要修改线程2以在请求锁B之前请求锁定A).


Cha*_*ana 5

  Thrd 1 --- Lock A        - atmpt lock on B -   
         \                /                   \
          \              /                     \           
           \            /                       \         
            --- Lock A /                         --- wait for lock on B

  Thrd 2--- Lock B         - atmpt lock on A -   
         \                /                   \
          \              /                     \           
           \            /                       \         
            --- Lock B /                         --- wait for lock on A
Run Code Online (Sandbox Code Playgroud)

线程1运行,锁定A,执行一些操作,并被线程2中断,锁定B,执行某些操作并被线程1中断,尝试锁定B,但线程2已锁定B,因此线程1等待,并被中断线程2尝试锁定A,但线程1锁定A,因此线程2必须等待.

两个线程都在等待另一个线程释放对他们试图获得锁定的资源的锁定...

僵局


pax*_*blo 5

我宁愿用与计算机完全无关的术语解释它,因为这通常是获得想法的最佳方式.

我有一个五岁的儿子和一个三岁的女儿.两人都希望做同样的着色书.

当儿子抓住书时,女儿抓住铅笔.在他们得到对方之前,他们都不会放弃他们拥有的东西.

那是僵局.它没有比这更简单.

您的进程(或子进程)等待彼此等待,并将继续无限期地等待,直到其他一些高级进程(如Dad)进入并打破僵局.

至少对孩子们来说,你可以(有时)让他们中的一个看到原因并放弃他们的锁定.这通常不适用于计算机,因为除了等待该资源之外,进程没有做任何事情(尽管有时孩子也会进入这种状态).

遵循一条规则将保证不会发生死锁:

  • 所有执行线程以相同的顺序分配资源.

遵循一些额外的规则将使您的线程减少相互减速的可能性,但请记住,上述规则应优先于所有其他规则:

  • 仅在您需要时分配资源.
  • 一旦你完成它们就释放它们.