并发Haskell异常

use*_*543 23 concurrency multithreading haskell exception-handling exception

如何在并发Haskell程序中提供异常?

假设我们有一个进程,有多个线程,其中一个通过TCP连接与某些东西进行交互,我们得到一个信号(比如在*nix系统上).

该信号将传递给哪个(绿色)线程?

是否将它传递给"使用"套接字或"主"指定线程将接收的那个,并且它必须明确地执行a throwTo将异常发送到该(绿色)线程?

Rom*_*aka 1

POSIX 信号和 Haskell 异常之间没有自动对应关系。

\n\n

为了将信号转换为异常,需要有一个信号处理程序来执行 \xe2\x80\x94 向 Haskell 线程之一抛出异常的操作。哪个线程获得异常完全取决于信号处理程序的设置方式。

\n\n

默认情况下,GHC 仅为 SIGINT 设置这样的处理程序,并且该信号将异常传递到主线程。

\n\n

您可以为其他信号安装类似的处理程序

\n\n
import Control.Concurrent (mkWeakThreadId, myThreadId)\nimport Control.Exception (Exception(..), throwTo)\nimport Control.Monad (forM_)\nimport Data.Typeable (Typeable)\nimport System.Posix.Signals\nimport System.Mem.Weak (deRefWeak)\n\nnewtype SignalException = SignalException Signal\n  deriving (Show, Typeable)\ninstance Exception SignalException\n\ninstallSignalHandlers :: IO ()\ninstallSignalHandlers = do\n  main_thread_id <- myThreadId\n  weak_tid <- mkWeakThreadId main_thread_id\n  forM_ [ sigABRT, sigBUS, sigFPE, sigHUP, sigILL, sigQUIT, sigSEGV,\n          sigSYS, sigTERM, sigUSR1, sigUSR2, sigXCPU, sigXFSZ ] $ \\sig ->\n    installHandler sig (Catch $ send_exception weak_tid sig) Nothing\n  where\n    send_exception weak_tid sig = do\n      m <- deRefWeak weak_tid\n      case m of\n        Nothing  -> return ()\n        Just tid -> throwTo tid (toException $ SignalException sig)\n\nmain = do\n  installSignalHandlers\n  ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

但您也可以发挥创意并更改处理程序以将信号传递到其他线程。例如,如果只有一个线程使用套接字,您可以确保该线程收到异常。或者,根据您感兴趣的信号,也许您可​​以根据结构找出相关线程siginfo_t(请参阅sigaction(2))\xe2\x80\x94 也许是 si_fd 字段?

\n