Утечка памяти Thunk в результате функции карты
Я пишу многопоточную программу, которая использует mvars; в этом случае у меня есть поток, который периодически меняет список внутри mvar. К сожалению, есть утечка памяти. Кажется, возникает проблема, связанная с утечкой функции "идентификатор карты" (в реальной программе я использую что-то кроме идентификатора). Я просто не могу найти способ избежать этого - я играл с 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
2 ответа
Решение
После еще нескольких попыток эта, похоже, сработает:
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
Помимо утечки пространства, более ранняя версия также может иметь "утечку времени" в том смысле, что неоцененные thunks, помещенные в mvar, могут оцениваться принимающим потоком вместо отправляющего, возможно разрушая любой предполагаемый параллелизм.