如果我按Ctrl + C,这会引发异常(总是在线程0?).如果你愿意,你可以抓住这个 - 或者,更有可能的是,运行一些清理,然后重新抛出它.但通常的结果是以某种方式停止程序.
现在假设我使用Unix kill命令.据我了解,kill基本上将(可配置的)Unix信号发送到指定的进程.
Haskell RTS如何响应这一点?它在某处记录了吗?我会想象,在发送SIGTERM会有如按Ctrl + C相同的效果,但我不知道那是事实...
(当然,你可以使用kill发送与杀戮毫无关系的信号.再一次,我会想象 RTS会忽略,比方说,SIGHUP或者SIGPWR,但我不确定.)
bhe*_*ilr 17
谷歌搜索"haskell catch sigterm"让我看到System.Posix.Signals了这个unix包,它有一个相当漂亮的系统来捕捉和处理这些信号.只需向下滚动到"处理信号"部分.
编辑: 一个简单的例子:
import System.Posix.Signals
import Control.Concurrent (threadDelay)
import Control.Concurrent.MVar
termHandler :: MVar () -> Handler
termHandler v = CatchOnce $ do
putStrLn "Caught SIGTERM"
putMVar v ()
loop :: MVar () -> IO ()
loop v = do
putStrLn "Still running"
threadDelay 1000000
val <- tryTakeMVar v
case val of
Just _ -> putStrLn "Quitting" >> return ()
Nothing -> loop v
main = do
v <- newEmptyMVar
installHandler sigTERM (termHandler v) Nothing
loop v
Run Code Online (Sandbox Code Playgroud)
请注意,我必须使用MVar来告知loop是时候退出了.我尝试使用exitSuccessfrom System.Exit,但由于termHandler在一个不是主线程的线程中执行,它不能导致程序退出.可能有一种更简单的方法,但我以前从未使用过这个模块,所以我不知道.我在Ubuntu 12.10上测试了这个.
ben*_*ofs 13
在github上的ghc源代码中搜索"signal" 显示了installDefaultSignals函数:
void
initDefaultHandlers(void)
{
struct sigaction action,oact;
// install the SIGINT handler
action.sa_handler = shutdown_handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGINT, &action, &oact) != 0) {
sysErrorBelch("warning: failed to install SIGINT handler");
}
#if defined(HAVE_SIGINTERRUPT)
siginterrupt(SIGINT, 1); // isn't this the default? --SDM
#endif
// install the SIGFPE handler
// In addition to handling SIGINT, also handle SIGFPE by ignoring it.
// Apparently IEEE requires floating-point exceptions to be ignored by
// default, but alpha-dec-osf3 doesn't seem to do so.
// Commented out by SDM 2/7/2002: this causes an infinite loop on
// some architectures when an integer division by zero occurs: we
// don't recover from the floating point exception, and the
// program just generates another one immediately.
#if 0
action.sa_handler = SIG_IGN;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGFPE, &action, &oact) != 0) {
sysErrorBelch("warning: failed to install SIGFPE handler");
}
#endif
#ifdef alpha_HOST_ARCH
ieee_set_fp_control(0);
#endif
// ignore SIGPIPE; see #1619
// actually, we use an empty signal handler rather than SIG_IGN,
// so that SIGPIPE gets reset to its default behaviour on exec.
action.sa_handler = empty_handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGPIPE, &action, &oact) != 0) {
sysErrorBelch("warning: failed to install SIGPIPE handler");
}
set_sigtstp_action(rtsTrue);
}
Run Code Online (Sandbox Code Playgroud)
从那里,您可以看到GHC至少安装了SIGINT和SIGPIPE处理程序.我不知道源代码中是否隐藏了任何其他信号处理程序.