我正在通过实施餐饮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
调用导致它重新启动另一个原子块?
答案 0 :(得分:3)
不,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