当thunk被垃圾回收时,Haskell是否会丢弃spark?

16
例如:
x :: Maybe a
y :: a
y `par` x `pseq` (fromMaybe y x)

如果在计算x时发现其为Just ...,那么是否会立即停止并丢弃y的火花?更具体地说,我想搜索一个列表,但每次比较都很耗费资源。我想并行搜索,但希望在找到匹配项后将其余的比较结果丢弃。

1个回答

6
你是不是想用fromMaybe代替maybe
x `par` y `pseq` (fromMaybe y x)

您正在创建一个用于评估x而不是y的火花。因此,只有在评估y之后才会评估fromMaybe y x。也许您的意思是相反的:

y `par` x `pseq` (fromMaybe y x)

如果以上都是正确的,那么你的问题的答案是“不会”,一旦启动了 Spark(尽管如果还没有启动就会被丢弃)它将不会停止。您可以使用以下测试进行检查:
import Data.Maybe
import Control.Concurrent
import Control.Parallel
import System.IO.Unsafe
import System.Mem

{-# NOINLINE x #-}
x = unsafePerformIO $ do
  threadDelay 1000
  return (Just 1)

{-# NOINLINE y #-}
y = unsafePerformIO $ do
  print "will eval y"
  threadDelay 3000000
  print "did eval y"
  return (2 :: Int)

main :: IO ()
main = do
  print $ y `par` x `pseq` fromMaybe y x
  print "done"
  performGC
  threadDelay 4000000

输出结果:
"will eval y"
1
"done"
"did eval y"

您可以使用运行时统计功能+RTS -s来检查,其中包含多个垃圾回收的火花。

是的,你正如应该做的那样纠正了我的错误:),谢谢!所以我想要终止任务,必须使用并发并手动使用killThread来杀死线程。 - Petr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接