Haskell的STM`check`与明确使用`retry`是不同的吗?

时间:2015-06-25 02:42:15

标签: haskell stm

我正在通过实施餐饮philsophers问题来试验STM。

无论如何,我有以下定义。

data ChopStick = CS (TVar Bool)

takeChopstick :: ChopStick -> STM ()
takeChopstick (CS chopstick) = do
    isTaken <- readTVar chopstick
    check (isTaken)
    writeTVar chopstick True

此函数以原子方式调用:

atomically $ do
    takeChopstick leftChopstick
    takeChopstick rightChopstick

当使用上面的takeChopstick定义运行程序时,使用此定义运行它会遇到不同的结果:

takeChopstick :: ChopStick -> STM ()
takeChopstick (CS chopstick) = do
    isTaken <- readTVar chopstick
    if isTaken
        then retry
        else writeTVar chopstick True

特别是程序挂起。

check(hackage,stm-2.2.0.1)的源代码如下:

check :: Bool -> STM a
check b = if b then return undefined else retry

这似乎与我明确使用retry实际上相同。

check与明确使用retry的区别如何?是否进一步推动retry调用导致它重新启动另一个原子块?

1 个答案:

答案 0 :(得分:3)

不,check与明确使用retry没什么区别,我只是把这个论点混淆了check

解决方案是check isTakenFalse,即check $ not isTaken

takeChopstick :: ChopStick -> STM ()
takeChopstick (CS chopstick) = do
    isTaken <- readTVar chopstick
    check (not isTaken)
    writeTVar chopstick True