我正在编写一个多线程程序,它充分利用了mvars;在这种情况下,我有一个线程,周期性地更改mvar内的列表。不幸的是,有一个thunk内存泄漏。似乎有一种问题是'map id'(在实际程序中我使用的不是id的东西)函数泄漏。我只是找不到如何避免这种情况的方法 - 我正在使用'seq'而没有结果。什么是纠正泄漏的正确方法?
upgraderThread :: MVar [ChannelInfo] -> IO ()
upgraderThread chanMVar = forever job
where
job = do
threadDelay 1000
vlist <- takeMVar chanMVar
let reslist = map id vlist
putMVar chanMVar reslist
答案 0 :(得分:4)
经过几次尝试后,这个似乎有效:
upgraderThread chanMVar = forever job
where
job = do
threadDelay 1000
vlist <- takeMVar chanMVar
let !reslist = strictList $ map id vlist
putMVar chanMVar reslist
strictList xs = if all p xs then xs else []
where p x = x `seq` True
答案 1 :(得分:4)
除了空间泄漏之外,早期版本也可能有“时间泄漏”,因为放入mvar的未评估的thunk可能会被接收线程而不是发送线程评估,可能会破坏任何预期的并行性。