2013-01-20 58 views
0

我想知道爲什麼這個程序可以有死鎖死鎖 - 轉移方案

void transfer(int from, into to, double amount) { 
    sem_t *sem_from, *sem_to; 
    sem_from=get_sem(from); //function that obtains the semaphore from bank account argument 
    sem_to=get_sem(to); 
    sem_wait(sem_from); 
    sem_wait(sem_to); 
    withdraw(from, amount); 
    deposit(to, amount); 
    sem_post(sem_to); 
    sem_post(sem_from); 
} 

感謝。

+0

我們不是物理 - 需要更多信息。 –

+0

最有可能是由於獲取信號量的順序。 – AraK

+0

'get_sem'做什麼? – cnicutar

回答

2

假設有兩個併發運行的函數實例。第一種是從帳戶A向帳戶B轉移一些金額,而第二種從帳戶B向帳戶A轉移一些其他金額。如果發生第一個實例獲得A的鎖定並且同時第二個實例獲得B的鎖定,發生死鎖。

+0

不完全。在第一種情況下從'= A和'到'= B,在第二種情況下從'= B和'到'= A。所以第一個例子獲得對A的鎖定,對B的第二個鎖定,並且他們都等待。 –

+0

我該如何避免死鎖?謝謝。 – tomss

1

據我瞭解,如果函數的多個實例正在運行,然後如果任何函數(提取,存款)未能重置信號量,則其他函數將停止工作,因爲他們無法獲得信號量。

如果函數保證完成,那麼可以避免死鎖。

+0

假設sem_post正在重置sem .. – Arpit

1

我最初沒有注意到每個帳戶都有一個sem,而AraK值得接受的答案。

只是一個建議:如果退出存款功能不買貴的,只使用一個唯一的信號定義一個關鍵部分進行任何轉讓。在給定的時間只有一次轉移。

sem_t *sem_tranfer; // to be created and initialized somewhere 

void transfer(int from, into to, double amount) { 
    sem_wait(sem_transfer); 
    withdraw(from, amount); 
    deposit(to, amount); 
    sem_post(sem_transfer); 
}