我正在通过实现哲学家就餐问题来试验 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
调用进一步向下推会导致它重新启动不同的原子 block 吗?
最佳答案
不,check
与使用 retry
没有什么不同明确地说,我只是将参数混淆为 check
.
解决方案是check
那isTaken
是False
,即 check $ not isTaken
.
takeChopstick :: ChopStick -> STM ()
takeChopstick (CS chopstick) = do
isTaken <- readTVar chopstick
check (not isTaken)
writeTVar chopstick True
关于haskell - Haskell 的 STM `check` 与显式使用 `retry` 不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31040329/