ããã¯Haskellスペースリーク Advent Calendar 2015ã®14æ¥ç®ã®è¨äºã§ãã
ã¹ã¬ãããªã¼ã¯ã¨ã¯ä¸è¬çã«ãçµäºããããã¨ãå¿ããã¹ã¬ãããæ®ãç¶ãããã¨ãè¨ããããã¯çµäºããå¿ããã®ãæªãã¨ããä»ãªããä¸æ¹ã§ãGHC ã§ã¯ãã¹ã¬ãããçµäºãããã«ãããããããã¹ã¬ããã®ã¡ã¢ãªé åãCGã«ååãããªãäºæ ãèµ·ããããããã®è¨äºã¯ããã®äºçªç®ã®ã¹ã¬ãããªã¼ã¯ã«ã¤ãã¦èª¬æããã
ThreadId
ThreadIdã¯ãååãããã¦ãã以ä¸ã®ããã«è¡¨ç¤ºããã¦ããOrdã®ã¤ã³ã¹ã¿ã³ã¹ã§ããã¨ããããããåãªãçªå·ã®ããã«æããã
> forkIO (return ()) >>= print ThreadId 88
ããããThreadIdã®ããã¥ã¢ã«ã注ææ·±ãèªãã¨ã以ä¸ã®ãããªãã¨ãæ¸ãã¦ããã
GHCã®å®è£ ã§ã¯ãThreadIdã¯æ¬è³ªçã«ã¹ã¬ããã«å¯¾ããåç §ã§ããã ããã¯ãThreadIdãæ¨ã¦ãªããã°ãGCãã¹ã¬ããèªä½ãååã§ããªããã¨ãæå³ããã ãã®ããããªä»æ§ã¯ãå°æ¥ä¿®æ£ãããã ããã
ãªãã¨ãããã¨ã ãããThreadId ãã©ããã«ä¿æãã¦ããã¨ãã¹ã¬ããã¯çµäºãã¦ãéæ¾ãããªãã®ã ãããã¯ãå®éã« Warp ã§åé¡ã¨ãªã£ãã
å¼±ãåç §
ããã解決ããã«ã¯ãThreadIdã¨ããå¼·ãåç §ãå¼±ãåç §ã«å¤æããã°ããããã®ããã®é¢æ°ã§ãã mkWeakThreadId ã®ã·ã°ããã£ã¯ä»¥ä¸ã®éãï¼
mkWeakThreadId :: ThreadId -> IO (Weak ThreadId)
ThreadIdã®ä»£ããã«ãWeak ThreadId ãä¿æããããã ãWeak a ã¯ãEq ã§ã Ord ã§ããªãã®ã§ããªã¹ããããã«ããæ ¼ç´ã§ããªããã¨ã«æ³¨æã
Weak ThreadId ãã ThreadId ãåãåºãã«ã¯ãSystem.Mem.Weak ã® deRefWeak ã使ãã
deRefWeak :: Weak v -> IO (Maybe v)
deRefWeakã¯ãå¼±ãåç §ã®å ã«å®éã«ãã¼ã¿ãããã° Just ããããã§ãªããã° Nothing ãè¿ããThreadId ã¨ä¸ç·ã«ä½¿ãã³ã¼ãã®ä¾ã以ä¸ã«ç¤ºãã
do mtid <- deRefWeak wtid case mtid of Nothing -> return () Just tid -> killThread tid
ã¾ã¨ã
Haskellã®ä¸è¬çãªãã¼ã¿æ§é ã¯ãæ示çã«ã¯è§£æ¾ã§ããªããããããã¹ã¬ããã¯çµäºãããã¨ã§è§£æ¾ã§ããç¹æ®ãªãã¼ã¿æ§é ã§ãããä»ã®è¨èªããããã°å½ããåãªãã®ãã¼ã¿æ§é ã«ã¯ãä»ã®è¨èªãè¦ããããã¦ããã®ã¨å種ã®å±éºæ§ãããã