我被困在理解 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/

10-12 17:08