2017-09-06 105 views
-1

無法瞭解從高爾文第9版第7章死鎖頁326如果可以動態獲取鎖,則強制鎖定順序不能保證鎖死。這是什麼意思?

堂堂一個鎖定順序並不能保證防止死鎖如果鎖可動態獲取採取以下文字。例如,假設我們有一個在兩個賬戶之間轉移資金的功能。爲了防止競爭條件,每個帳戶具有從一個get鎖()函數獲得如在下面的程序中所示的相關聯的互斥鎖:

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(checking account, savings account, 25); 

,另一個可能會調用

transaction(savings account, checking account, 50); 

任何人可以幫我瞭解這裏的含義是什麼?

回答

1

作者是馬虎。所有的文字真的告訴你,如果你沒有施加嚴格的鎖定順序,施加嚴格的鎖定順序不會對你有所幫助。

該示例中的代碼沒有強加任何鎖定順序,因爲它以參數進入的任何順序鎖定鎖定。想象一下,如果有兩個併發呼叫會發生什麼情況:一個線程調用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); 
}