16

Ctrl+C を押すと、例外がスローされます (常にスレッド 0 でしょうか?)。必要に応じてこれをキャッチできます。または、クリーンアップを実行してから再スローする可能性が高くなります。しかし、通常の結果は、何らかの方法でプログラムを停止させることです。

ここで、Unixkillコマンドを使用するとします。私が理解しているように、kill基本的には(構成可能な)Unixシグナルを指定されたプロセスに送信します。

Haskell RTS はこれにどのように応答しますか? それはどこかに文書化されていますか?送信するとCtrlSIGTERM +C を押すのと同じ効果があると思いますが、実際にはわかりません...

(そしてもちろん、 を使用killして、殺害とはまったく関係のない信号を送信することもできます。繰り返しますが、 RTSは無視するか、SIGHUPまたはと言うとSIGPWR思いますが、確かなことはわかりません。)

4

2 に答える 2

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

終了する時が来たことを知らせるために MVar を使用しなければならなかったことに注意してくださいloopexitSuccessfromを使ってみましたSystem.ExittermHandler、メインスレッドではないスレッドで実行されるため、プログラムを終了させることはできません。もっと簡単な方法があるかもしれませんが、このモジュールを使用したことがないので、わかりません。これをUbuntu 12.10でテストしました。

于 2013-08-25T15:57:04.607 に答える