STM のアトミックな概念を理解するのに行き詰まりました。
例を挙げて説明します
import Control.Concurrent
import Control.Concurrent.STM
import Control.Monad
import qualified Data.Map as Map
main :: IO ()
main = do
d <- atomically$ newTVar Map.empty
sockHandler d
sockHandler :: TVar (Map.Map String Int)-> IO ()
sockHandler d = do
forkIO $ commandProcessor d 1
forkIO $ commandProcessor d 2
forkIO $ commandProcessor d 3
forkIO $ commandProcessor d 4
forkIO (threadDelay 1000 >> putStrLn "Hello World?")
threadDelay 10000
return ()
commandProcessor :: TVar (Map.Map String Int)-> Int-> IO ()
commandProcessor d i= do
addCommand d i
commandProcessor d i
addCommand :: TVar (Map.Map String Int) ->Int -> IO ()
addCommand d i = do
succ <- atomically $ runAdd d
putStrLn $"Result of add in " ++ (show i)++ " " ++( show succ)
runAdd d =do
dl <- readTVar d
let (succ,g)= if Map.member "a" dl
then
(False,dl)
else
(True,Map.insert "a" 9 dl)
writeTVar d g
return succ
サンプル出力は次のようになります。
add in 1 の結果 True add in 4 の結果 False add in 1 の結果 false add in 2 の FalseResult add in 3 False Hello World? 4 False を加算した結果
add in 1 の結果 False add in 2 の結果 False add in 3 の結果 False add in 4 の結果 False
add in 1 の結果 False add in 2 の結果 Falseadd in 3 の結果 Falseadd in 4 の結果 False
add in 1 の結果 False add in 2 の結果 Falseadd in 3 の結果 Falseadd in 4 の結果 False
add in 1 の結果 False add in 2 の結果 Falseadd in 4 の結果 Falseadd in 3 の結果 False
add in 1 の結果 False add in 4 の結果 Falseadd in 2 の結果 Falseadd in 3 の結果 False
add in 1 の結果 False add in 4 の結果 False add in 2 の結果 False add in 3 の結果 False
add in 1 の結果 False add in 4 の結果 False
add in 2 の結果 Falseadd in 3 の結果 False
add in 1 の結果 False add in 4 の結果 False
add in 2 の結果 False add in 3 の結果 False add in 1 の結果 False add in 4 の結果 False
add in 2 の結果 Falseadd in 3 の結果 False
add in 1 の結果 False add in 4 の結果 False
私が原子的に読んだとき
. これは、トランザクションが使用している変数を他のスレッドが変更することなく、トランザクション内のすべての操作が完全に完了するか、またはトランザクションが失敗し、トランザクションが開始される前の状態にロールバックされることを意味します。つまり、アトミック トランザクションは完全に完了するか、まったく実行されていないかのようになります。
では、場合によっては succ の「リターン」が決して起こらないという問題がありますか? つまり、行 succ <- アトミックに $ runAdd d putStrLn $"Result of add in " ++ (show i)++ " " ++( show succ)
「add in ?i の結果」の出力を与える (「まったく実行されなかったかのように」)