2011-07-08 87 views
8

我正在编写一个多线程程序,它使mvars的使用变得相当流畅;在这种情况下,我有一个线程周期性地改变mvar中的列表。不幸的是,有一个thunk内存泄漏。似乎有一个问题,'地图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 

回答

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   
+6

您在'strictList'中使用的模式被'deepseq'推广;见http://hackage.haskell.org/packages/archive/deepseq/latest/doc/html/Control-DeepSeq.html – acfoltzer

4

除了空间泄漏,早期版本也可能有一个“时间泄漏”的未计算的thunk放入mvar可能会被接收线程而不是发送线程评估,可能会破坏任何预期的并行性。