GoConでGoによるコマンド起動と停止について話してきました
嬉しいことに、Go Conference 2019 Springのプロポーザルが通ったので、自作のtimeoutパッケージを例にしながらGoからコマンドを起動して停止させる方法について話してきました。
https://junkyard.song.mu/slides/gocon2019-spring/#0
コマンド起動と停止というと簡単な話に聞こえるかも知れませんが、実はちゃんとやるためには考慮すべき事柄があります。そのあたり、GNU timeoutのソースコードも交えながら説明しました。結構面白い話ができたんじゃないかと思います。
github.com/Songmu/timeoutは単にコマンドをタイムアウトさせる目的だけではなく、contextでコマンドを正しく停止させるのにも有用なので是非お使いください。
プロセス停止に関しては大体以下のようなことをお話しました。
- Go標準の
exec.CommandContext
はコマンド停止はできるものの、SIGKILLで停止させる仕様なので困ることがある - そのプロセスへのSIGKILL発行なので、孫プロセスが孤児プロセスになってしまう懸念もある
- timeoutパッケージではSIGTERMを送り、それでも止まらなかったら指定秒後にSIGKILLを送る
- Songmu/timeoutもGNU timeoutもプロセスではなくプロセスグループに対してもシグナルを送れるようになっている
- Songmu/timeoutは呼び出したコマンドをプロセスグループリーダーにしているが、GNU timeoutは自分自身をプロセするグープリーダーにしている点が異なる
- 対象プロセスがSIGSTOP/SIGTSTPで一時停止している場合には、シグナルを送ってもプロセス再開まではシグナルを受け取らないため、SIGCONTで叩き起こすこともしている
GoConは実践の話が多くて面白かった。システムプログラミング的なのは少なめだったので、また話す機会があればそういうことを話せれば良いかな、とも思っています。