Part V: 同期と排他制御¶
概要¶
本章では、STM を使ったデッドロックフリーな銀行口座を学びます。
銀行口座(STM)¶
import Control.Concurrent.STM
-- | A thread-safe bank account using STM
data BankAccount = BankAccount
{ accountId :: Int
, accountBalance :: TVar Int
}
-- | Create a new bank account
newBankAccount :: Int -> Int -> IO BankAccount
newBankAccount accId initialBalance = do
balance <- newTVarIO initialBalance
return $ BankAccount accId balance
-- | Get the current balance
getBalance :: BankAccount -> IO Int
getBalance account = readTVarIO (accountBalance account)
-- | Deposit money
deposit :: BankAccount -> Int -> IO ()
deposit account amount = atomically $
modifyTVar' (accountBalance account) (+ amount)
-- | Withdraw money
withdraw :: BankAccount -> Int -> IO Bool
withdraw account amount = atomically $ do
balance <- readTVar (accountBalance account)
if balance >= amount
then do
writeTVar (accountBalance account) (balance - amount)
return True
else return False
アトミック送金(デッドロックフリー)¶
-- | Transfer money between accounts atomically
transfer :: BankAccount -> BankAccount -> Int -> IO Bool
transfer from to amount = atomically $ do
fromBalance <- readTVar (accountBalance from)
if fromBalance >= amount
then do
modifyTVar' (accountBalance from) (subtract amount)
modifyTVar' (accountBalance to) (+ amount)
return True
else return False
STM の利点¶
| 特徴 | 説明 |
|---|---|
| デッドロックフリー | 自動リトライによる解決 |
| 合成可能性 | 複数の操作を組み合わせ可能 |
| 例外安全 | ロールバックによる一貫性維持 |
| 簡潔さ | ロック順序を考慮不要 |
STM vs MVar¶
| 機能 | STM | MVar |
|---|---|---|
| 合成 | 可能 | 困難 |
| デッドロック | フリー | 可能性あり |
| パフォーマンス | やや低い | 高い |
| 複雑さ | 低い | 高い |
次のステップ¶
Part VI では、ノンブロッキング I/O を学びます。