2014-10-17 8 views
1

다음 코드 섹션은 어떻게 코드 블록에 treadDelay를 포함하스켈의 STM 코드에 threadDealy를 추가하는 방법은 무엇입니까?

type GNum = TVar Int 
-- updateNum will read a num and add the given value to it 
updateNum :: GNum -> Int -> STM() 
updateNum n v = 
    do t <- readTVar n 
    writeTVar n (v + t) 
-- transaction read a number say n1 and replace value of n2 by n1 + v. 
-- v is a given value. 
myTransaction :: GNum -> GNum -> Int -> IO() 
myTransaction n1 n2 v = 
atomically $ do 
     x <- readTVar n1 
     y <- readTVar n2 
     let z = (quot x v) 
     -- threadDelay (10^6 * 2) --How to include this? 
     updateNum n2 z 

ghci에 기록 된?
왜 내가 이것을 원하니? 사실 나는 다른 스레드 사이에 n1의 값을 업데이트 할 수 있도록 스레드 T1이 대기하도록하고 싶었습니다. 따라서 T1은 커밋시 인 이 일치하지 않게됩니다. 내가 다음과 같은 오류 보여 줄 threadDelay (* 2 10^6)를 포함하면

: - 당신이 테스트를위한 시스템에 인공 압력을 추가하려는 경우

Couldn't match type 'IO' with 'STM' 
exptected type: STM() 
    Acutal type: IO() 
In a stmt of a 'do' block: threadDelay (10^6*2) 
In the second argument o f`($)`, namely 
    `do { x <- readTVar n2; 
     y <- readTVar n2; 
---- 
---- 

답변

0

를, 그것은 속이 괜찮아 .

atomically $ do 
    x <- readTVar n1 
    y <- readTVar n2 
    let z = quot x v 
    return $! unsafePerformIO (threadDelay (10^6 * 2)) 
    updateNum n2 z 

당신은 System.IO.Unsafe에서 unsafePerformIO를 얻을 수 있습니다.

+0

감사합니다. luqui. 또한 루프를 실행하여이 문제를 해결하려고했습니다. 두 경우 모두 결과는 ** updateNum n2 z ** 문에 영향을 미치지 않습니다. 어떤 딜레이 트랜잭션이 update 문을 실행하면 원하는 것을 얻을 수 있습니다. –

+2

[unsafeIOToSTM] (http://haddocks.fpcomplete.com/fp/7.8/20140916-162/base/GHC-Conc-Sync.html#v:unsafeIOToSTM)을 사용하는 것이 좋습니다. 공유를 사용하면 위의 지연이 한 번만 발생할 수도 있습니다 (그러나이 경우는 확실하지 않습니다). –