我在程序中结合使用async
库和stm
。
主线程派生两个运行的线程,直到其中一个(可能是一个)遇到解决方案为止。解决方案通过TMVar返回。找到解决方案后,它们中的任何一个都不会等待任何TMVar
的调用,除非调用putTMVar
,并且保证其中一个可以永久运行,除非被杀死。因此,如果至少有一个子线程不执行任何阻塞的STM事务(或死亡),那么我怎么可能会“在STM事务中无限期阻塞线程”(似乎每二十次发生一次)。存储结果。
请注意,两个子线程使用TVar
与彼此进行了某种通信,但没有与TMVar
进行通信。
简化代码:
main :: IO ()
main = do
output <- newEmptyTMVar
result <- withAsync (child1 output) $ \_ -> withAsync (child2 output) $ \_ ->
let go = do
result <- atomically $ takeTMVar output
if someCondition result
then return result
else go
in go
print result
child1 :: TMVar Result -> IO ()
child1 output = go 0
where
go i = do
case computation1 i of
Nothing -> return ()
Just x -> atomically $ putTMVar x
go (i + 1)
child2 :: TMVar Result -> IO ()
-- Does some other stuff, but also only interacts with its argument to
-- give back a result, same as child1.