2011-07-08 8 views
8

mvarsをかなり使用するマルチスレッドプログラムを作成しています。この場合、私は定期的にmvar内のリストを変更するスレッドを持っています。残念ながら、サンクのメモリリークがあります。 '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 

答えて

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

スペースリーク以外にも、以前のバージョンも中に置か未評価のサンクその中で「時間リーク」を有していてもよいですmvarは、送信スレッドの代わりに受信スレッドによって評価される可能性があり、意図された並列性を破壊する可能性があります。

関連する問題