다음 코드 (Pl. myTransaction 참조)에서 특정 지연 후에 값을 읽는 방식으로 TVar n1에서 원자 적으로 읽고 다른 TVar n2를 업데이트하려고합니다. 문제는 하나의 원자 블록을 다른 원자 블록으로 전달할 수 없다는 것입니다. 도와주세요하나의 원자 블록에서 다른 원자 블록으로 값을 전달하는 방법
The last statement in a 'do' loop must be an expression
let y = (x + v)
SimpleSTM1.hs:24:43: Not in scope: 'y'
:
module SimpleSTM
where
import Control.Concurrent.STM
import Control.Concurrent
import System.IO.Unsafe
import System.Random
type GNum = TVar Int
updateNum :: GNum -> Int -> STM()
updateNum n v = writeTVar n v
myTransaction :: GNum -> GNum -> Int -> IO()
myTransaction n1 n2 v = do
atomically $ do
x <- readTVar n1
let y = (x + v) -- Getting Error: Not an expression
randomDelay
atomically $ updateNum n2 y -- Getting Error: Not in scope: 'y'
randomDelay = do delay <- getStdRandom(randomR (1,3))
threadDelay (delay * 1000000)
main :: IO()
main = do n1 <- newTVarIO 1
n2 <- newTVarIO 1
n1v <- readTVarIO n1
n2v <- readTVarIO n2
putStrLn ("n1 = " ++ (show n1v) ++ " n2= " ++ (show n2v))
forkIO (myTransaction n1 n2 1)
forkIO (myTransaction n2 n1 2)
forkIO (myTransaction n2 n1 3)
n1v <- readTVarIO n1
n2v <- readTVarIO n2
putStrLn ("n1 = " ++ (show n1v) ++ " n2= " ++ (show n2v))
코드
는 다음과 같은 오류를 생성합니다. 미리 감사드립니다.
Chi. 당신이 말했듯이, 그것은 원자가되지 않아서 제 목적을 해결할 수 없습니다. –
@AmmlanGhosh 그러나 왜 STM 모나드 내에 지연이 필요한지 명확하지 않습니다. 어떤 "진짜"목적이 아니라 그것을 실험하기위한 것일까 요? 그런 다음 어쨌든 "안전하지 않은"물건을 사용하면됩니다. – chi
친애하는 Chi, 새로운 코드를 Answer로 추가했습니다. 트랜잭션을 다시 실행하는 방법을 확인하고 싶습니다. 코드를 확인하십시오. –