エンジニアとして働き始めてすぐの頃、先輩に紹介してもらって『なるほどUnixプロセス』という本を読んだ。プロセスの操作方法やプロセスの周りにある技術を Ruby のコード例を添えて解説している本である。

最近仕事で Ruby 2.x にて並列処理したい状況になったので再読した。Ruby 2.x には 3.0 から入った並列処理機構である Ractor がないので、マルチプロセスかマルチスレッドで並列処理することになる。
前回本書を読んだのは1年前だった。改めて読むと、1年で培った経験や知識も相まってより脳に定着した気がする。

内容紹介

プロセス、ゾンビプロセスとデタッチ、シグナル、デーモンプロセス、プロセス間通信などについての詳しい説明と Ruby で実践するためのコード例が載っている。加えて、これらの理解を助けるために Unix の技術の説明もある。例えば、man ページの読み方、システムコール、pid、ファイルディスクリプタなどである。

上記のキーワードに興味をもっているものの理解が浅いと思っているなら一読されたし。達人出版会なので購入すれば pdf でダウンロードできる。

なるほどUnixプロセス ― Rubyで学ぶUnixの基礎 Jesse Storimer, 島田浩二(翻訳), 角谷信太郎(翻訳)
naruhodo_unix_process_book

記事の残りのパートでは、再読して印象に残った点を、本のネタバレにならないように気をつけて書く。

fork(2) を使えばマルチコアプログラミングなのか?

fork(2) で子プロセスを生成すれば、必ず並列処理ができるわけではない。

例えばコンピュータが4つの CPU を備えているとする。fork して子プロセスを複数作り、それぞれが別の CPU で処理されればマルチコアで並列処理されたことになる。しかし、 CPU の稼働状況によっては単一の CPU で処理されることもありうる。

CoW フレンドリ

親プロセスのコピーを毎回作るオーバーヘッドを緩和するために、Unix は Copy on Write を採用している。書込みが必要になるまでメモリをコピーしない仕組みである。

Ruby 1.9 以下のバージョンは CoW が動作していなかったが、2.0 以上では CoW が動くようになっている。2.0 から入った Bitmap Marking により GC が改善され、CoW フレンドリになった。

Ruby 2.0.0 の GC 改善 - Rubyist Magazine

標準入力、標準出力、標準エラー出力もファイルディスクリプタ

すべての Unix プロセスは、3つのファイルディスクリプタを開いた状態で作られる。標準入力、標準出力、標準エラー出力である。

irb(main):001:0> STDIN.fileno
=> 0
irb(main):002:0> STDOUT.fileno
=> 1
irb(main):003:0> STDERR.fileno
=> 2

Ruby でシステムコールを呼ぶ

Kernel.#syscall メソッドが用意されており、Ruby から直接システムコールを呼ぶことができる。なお、筆者の macOS では Kernel.syscall メソッドは対応しておらず呼び出せなかった

[EXCEPTION] NotImplementedError:
実行環境がこのメソッドに対応していないとき発生します。

おわりに

あなたがプロセスを理解したいと思っており、Ruby を読み書きできるならぴったりの教材だと思う。

訳者の一人であるえにしテックの島田さんがプロセスや Unix について書かれた記事もあるので、合わせて読まれたい。

『なるほどUnixプロセス』を読む前にちょっとだけナルホドとなる記事 - Rubyist Magazine