2014-02-21 6 views
1

Я очутившись пытаюсь написать что-то вроде этого:Очистка дочерних потока, когда основной поток завершается

main = do t1 <- forkIO (forever io) 
      t2 <- forkIO (forever io) 
      forever io 
      `finally` traverse_ killThread [t1,t2] 

Но t1 и t2 не могут быть доступны в finally, потому что это вне монады.

Поскольку здесь действия IO запускаются вечно, моя главная задача - дать возможность потоку выйти из строя в случае прерывания пользователя или IOException в последнем действии ввода-вывода.

Я знаю, что такие пакеты, как async и threads, отлично подходят для этого, но можно ли это сделать с помощью простых примитивов параллелизма?

Кстати, было бы неплохо, чтобы среда выполнения автоматически отправляла killThread всем дочерним потокам. Когда ты этого не хочешь?

ответ

2

Только что понял, что нет никаких проблем, включая finally в блоке монадического кода.

main = do t1 <- forkIO (forever io) 
      t2 <- forkIO (forever io) 
      forever io `finally` traverse_ killThread [t1,t2] 

Я не отмечаю этот вопрос как ответ, если кто-то видит что-то не так с этим.

0

Вам не нужно убивать дочерние потоки, потому что время выполнения Haskell убивает их, когда основной поток завершается в любом случае. Обычно вы пишете код в главном, чтобы дождаться завершения дочерних потоков, прежде чем завершать себя.

+0

Я согласен с вами в том, что обычный шаблон будет для основного потока ждать завершения дочерних потоков. Но даже если он ждет, что происходит, когда основной поток получает прерывание пользователя. Как среда выполнения убивает дочерние потоки? Разве это распространяет исключение прерывания пользователя или бросает для них исключение «ThreadKilled»? Я хотел бы получить доступ к исключению в дочерних потоках, чтобы я мог выполнить некоторую очистку. –

Смежные вопросы