我被困在理解 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
示例输出将是这样的:
当我以原子方式阅读时
那么问题来了,在某些情况下,succ 的“回归”可能永远不会发生吗?
那是可以的
succ 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
在您的情况下,事务将始终运行并始终完成。由于冲突,它可能会在第二次或第三次尝试时完成,但这对用户来说是不可见的。 STM 确保 Action 以原子方式发生,即使它需要经过几次才能成功完成。
关于haskell - 试图理解 Haskell STM 简单的东西,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4872411/