我正在做什么防止死锁?

时间:2018-01-20 00:43:27

标签: multithreading concurrency deadlock

我有12个资源(r_1,r_2,...,r_12),以及我的线程尝试访问的12个相应的锁(l_1,l_2,...,l_12)。每个线程都需要一个特定的资源序列来进行操作。例如,线程1需要r_1,r_3和r_5。线程2需要r_1,r_7,r_8,r_10。

现在我基本上已经完成了从1到12的资源排序,让每个线程按此顺序锁定所需的资源(升序),然后当线程完成时,我以相反的顺序解锁它们(降序)订单)维持订单。

所以我的问题是,在这种情况下我是否阻止死锁?或者会发生僵局吗?

1 个答案:

答案 0 :(得分:2)

TL; DR :是的,这个系统完全不受僵局的影响。在任何时间点,持有编号最大的锁的线程必须能够取得进展,因为它无法等待获取其他进程持有的任何锁。更正式地说,您的条件确保所有进程锁定获取的总排序,这反过来确保永远不会发生循环等待。循环等待是死锁的必要前提。

详细信息:为了发生死锁,必须满足以下所有四个条件(请参阅相关的Wikipedia):

  1. 相互排斥 - 即并发进程正在访问不可共享的资源。根据定义,锁定是不可共享的(出于这个原因,它们也被称为互斥锁)。

  2. 等待 - 至少有一个进程正在尝试访问多个资源,并且通过保留其中一些资源然后等待其他资源来执行此操作。这种情况可能适用于您的情况,具体取决于程序的确切语义。

  3. 无抢占 - 进程无法通过其他进程从其中获取资源。再次,这是我们正在使用的锁的属性。

  4. 循环等待 - 有一个进程循环,每个进程等待下一个进程持有的资源。这种情况不适用。考虑一个线程A,等待访问锁L_i。该锁必须由线程B保持,线程B已经从索引1到i获得了它所需的所有锁。结果,B不能等待A.类似地,B正在等待获取其下一个锁L_j(其中j> i按获取锁的顺序)的任何线程都不能等待任何锁定指数1到j。通过归纳,该系统中不存在依赖循环。

  5. 在并发编程中,前三种情况通常由您正在开发的上下文(正在使用并发原语等)设置,而最后一种情况可以通过聪明来避免。