⇤ ← 2013-05-31 08:49:24時点のリビジョン1
サイズ: 2112
コメント:
|
← 2013-05-31 11:35:41時点のリビジョン2 ⇥
サイズ: 2118
コメント:
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 33: | 行 33: |
ただこれメインスレッドに例外投げてるだけなので自作の例外か,(もしあるなら)ダミーの何も表さない例外を使うほうがいい気がする. そしてAsyncExceptionの型コンストラクタにUserInterruptとかいうそのものずばりなのがあった. | ただこれメインスレッドに例外投げてるだけなので自作の例外か,(もしあるなら)ダミーの何も表さない例外を使うほうがいい気がする. そしてAsyncExceptionのデータコンストラクタにUserInterruptとかいうそのものずばりなのがあった. |
Haskellでのシグナルハンドリング
System.Posix.Signalsに必要なものがある. unixのシグナル処理apiの単純なラッパのようだ.
シグナルをキャッチして終了処理を行う
すこしハマったのでメモ. Ctrl-CでCursesの終了処理を実行させたかった. http://stackoverflow.com/questions/13441676/how-to-write-ctrl-c-handler-in-haskell
installHandlerで登録されたシグナルハンドラは別スレッドで実行される. そんでもってghcではプログラムの終了を行えるのはメインスレッドのみ. というわけで普通に終了処理書いてもうまく動かない. 上のリンクではhandler内部でkillThread関数にメインスレッドのスレッドIDを渡している.
こんなコードを書いた
initialize :: IO () initialize = do mainThreadId <- myThreadId installHandler sigINT (Catch (teardown>>killThread mainThreadId)) Nothing installHandler sigTERM (Catch (teardown>>killThread mainThreadId)) Nothing initCurses keypad stdScr True echo False -- noecho teardown :: IO () teardown = endWin main = do initialize handle handler mainloop where handler :: AsyncException -> IO () -- data AsyncException = ThreadKilled | ... handler e = exitSuccess
ただこれメインスレッドに例外投げてるだけなので自作の例外か,(もしあるなら)ダミーの何も表さない例外を使うほうがいい気がする. そしてAsyncExceptionのデータコンストラクタにUserInterruptとかいうそのものずばりなのがあった.
というわけで書き直した
initialize :: IO () initialize = do initCurses keypad stdScr True echo False -- noecho teardown :: IO () teardown = endWin main = do initialize handle handler mainloop where handler :: AsyncException -> IO () -- data AsyncException = ThreadKilled | UserInterrupt | ... handler e = teardown >> exitSuccess
動いた. シグナルハンドラ自分で設定する必要なかった.