如果可以动态获取锁,则强制执行锁定顺序并不能保证防止死锁。这是什么意思?

时间:2017-09-06 06:52:39

标签: multithreading operating-system deadlock

无法理解以下文字取自高尔文第9版第7章死锁页面。

如果可以动态获取锁,则强制执行锁定顺序并不能保证防止死锁。例如,假设我们有一个在两个账户之间转移资金的功能。为防止竞争条件,每个帐户都有一个关联的互斥锁,该锁是从get lock()函数获得的,如以下程序所示:

void transaction(Account from, Account to, double amount)
{ 
       mutex lock1, lock2; 
       lock1 = get lock(from); 
       lock2 = get lock(to);

       acquire(lock1);
          acquire(lock2);
            withdraw(from, amount);
            deposit(to, amount);
          release(lock2);
       release(lock1);
}

如果两个线程同时调用transaction()函数,转置不同的帐户,则可能出现死锁。也就是说,一个线程可能会调用

transaction(checking account, savings account, 25);

,另一个可能会调用

transaction(savings account, checking account, 50);

有人可以帮我理解这里的意思吗?

1 个答案:

答案 0 :(得分:2)

提交人很草率。所有文字都告诉你的是,如果你没有强制执行严格的锁定命令,强加一个严格的锁定命令就不会帮助你。

示例中的代码没有强加任何锁定顺序,因为它以参数的任何顺序锁定锁。想象一下如果有两个并发调用会发生什么:一个线程调用transaction(A, B)同时调用transaction(B, A)时间,另一个线程调用void transaction(Account from, Account to, double amount) { mutex lock1, lock2; if (from.getAccountNumber() < to.getAccountNumber()) { lock1 = from.getLock(); lock2 = to.getLock(); } else { lock1 = to.getLock(); lock2 = from.getLock(); } acquire(lock1); acquire(lock2); withdraw(from, amount); deposit(to, amount); release(lock2); release(lock1); } 。两个线程将各自尝试以与另一个相反的顺序锁定相同的两个锁。这是死锁的经典方法。

修复示例以便它确实强制执行严格的命令的方法是使锁定顺序显式化。

{{1}}