7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

HaskellでCtrl-Cを制御する

Last updated at Posted at 2015-04-28

SIGINT等のシグナルの扱い方です。

##tl;dr
System.Posix.Signalsを使います

2019/1/25 追記

WindowsでCtrl-Cを制御する方法については @kakkun61 氏の記事を参照してください
Haskell で Ctrl-C を制御する(Windows) - 趣味はデバッグ……


Ctrl-Cが押されたらクロージングの処理を伴って終了するプログラムを書いてみます。

import Control.Concurrent
import System.Posix.Signals

main :: IO ()
main = do
    tid <- myThreadId
    let handler = do
            putStrLn "goodbye!"
            killThread tid
    installHandler keyboardSignal (Catch handler) Nothing

    let loop n = do
            putStr $ show n ++ ", "
            threadDelay 1000000
            loop (n+1)
    loop 0

実行してみましょう

$ runhaskell Main.hs
0, 1, 2, 3, 4, 5, ^Cgoodbye!
Main.hs: thread killed
$

ちゃんとgoodbyeと出力されて終了しました!killThreadは例外を伴って終了するのでMain.hs: thread killedというメッセージが出てしまっています。もし気になるなら例外を握りつぶすかMVarを使って終了を監視する仕組みを作るといいでしょう。

肝心のSignalを制御する関数はinstallHandler :: Signal -> Handler -> Maybe SignalSet -> IO Handlerです。Signelには制御するSignal、HandlerにはSignalが投げられた時の処理、Maybe SignalSetには処理時にブロックする他のSignalを指定します。

Signalの値は予め用意されていて

Function Signal
keyboardSignal SIGINT
keyboardStop SIGTSTP
keyboardTermination SIGQUIT
openEndedPipe SIGPIPE

と言った感じです。

HandlerDefaultにすれば標準の動作を、Ignoreにすれば何もしなくなり、Catch (IO ())で処理を記述すればSignalが投げられた時の処理を記述することができます。上の例ではhandlerという関数にメッセージの表示とメインスレッドの停止の処理を書いてHandlerとして渡していました。

簡単に解説しましたがまだまだ色々な使い方ができるので是非一度System.Posix.Signalsを読んでみてください(^^)

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?