Jon*_*nke 3 haskell transactional-memory ghc
我无法理解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
Run Code Online (Sandbox Code Playgroud)
示例输出如下:
加入的结果1加入4的真实结果加入的结果为1加入的FalseResult加入2的FalseResult加入3个错误的Hello World?加4的结果为假
加入1的FalseResult加2的结果错误加3的结果错误加4的结果错误
添加的结果1添加的假结果2添加的FalseResult 3添加的FalseResult False
添加的结果1添加的假结果2添加的FalseResult 3添加的FalseResult False
添加的结果1添加的假结果2添加的FalseResult 4添加的FalseResult False
加1的结果加入4的FalseResult加2的FalseResult加3的FalseResult
添加1的FalseResult添加的结果4 False结果添加2 False结果添加3 False
添加的结果1 FalseResult of add in 4 False
添加的结果2 FalseResult of add in 3 False
添加的结果1 FalseResult of add in 4 False
添加的结果2个FalseResult of add in 3 False结果添加1个False结果添加4个False
添加的结果2 FalseResult of add in 3 False
添加的结果1 FalseResult of add in 4 False
当我读到原子的时候
.这意味着事务内的所有操作都完全完成,没有任何其他线程修改我们的事务正在使用的变量,或者它失败,并且状态被回滚到事务开始之前的状态.简而言之,原子事务要么完全完成,要么就好像它们根本就不运行一样.
所以对于这个问题,在某些情况下succ的"返回"是否永远不会发生?那就是行succ < - atomically $ runAdd d putStrLn $"添加的结果"++(show i)++""++(show succ)
给出"加入的结果?i"的输出("好像它们从未运行过")
如果事务确实被回滚,那么会发生什么是您的程序再次尝试.你可以想象实现是atomically这样的:
atomically action = do varState <- getStateOfTVars
(newState, ret) <- runTransactionWith action varState
success <- attemptToCommitChangesToTVars newState
if success
then return ret
else atomically action -- try again
Run Code Online (Sandbox Code Playgroud)
在您的情况下,交易将始终运行并始终完成.由于冲突,它可能在第二次或第三次尝试时完成,但是对于您(用户)来说这是不可见的.STM确保动作以原子方式发生,即使在能够成功完成之前需要花费一些时间.