我對併發編程非常陌生,所以我遇到了一個需要解決的死鎖問題。F#解決死鎖問題
因此,對於下面的代碼,它不打印任何我認爲肯定會出現死鎖的東西,儘管我不太確定它是如何發生的。
let sleepMaybe() = if (random 4) = 1 then Thread.Sleep 5
type account(name:string) =
let balance = ref 1000
member this.Balance = lock this <| fun() -> !balance
member this.Name = name
member this.Withdraw amount = balance := !balance - (sleepMaybe(); amount)
member this.Deposit amount = balance := !balance + (sleepMaybe(); amount)
member this.Transfer (toAcc:account) amount =
lock this <| fun() -> lock toAcc <| fun() -> toAcc.Deposit amount
this.Withdraw amount
let doTransfers (acc:account) (toAcc:account)() =
for i in 1..100 do acc.Transfer toAcc 100
printfn "%s balance: %d Other balance: %d" acc.Name acc.Balance toAcc.Balance
let q2main() =
let acc1=account("Account1")
let acc2=account("Account2")
startThread (doTransfers acc1 acc2)
startThread (doTransfers acc2 acc1)
q2main()
你需要發佈你的實際代碼。此代碼不起作用。 –
例如,它不是隨機的,而是隨機的(並且F#區分大小寫)。另外,我沒有知道的「startThread」,但有一個Thread.Start。 –
正如您從答案中看到的一樣,使用正確的鎖定是一項相當大的挑戰。作爲C#濫用者,我推薦學習如何正確使用鎖,但是儘可能地避免它們。通過傳遞消息而不是共享狀態可以更容易地解決大多數問題。查看F#中的MailboxProcessor。 – stmax