2010-01-14
■Perlでマルチプロセスデーモンを作るためのモジュール「Parallel::Prefork」に(Min|Max)SpareServers対応を追加した話 (もしくは read(2) / write(2) の atomicity)
Perl で複数のワーカープロセスを制御するためのモジュールとしては Parallel::ForkManager が古参なんだけど、このモジュールはプロセスを fork するだけで、シグナルを受信したらワーカープロセスを再起動とかそういうことができないので、自分は Parallel::Prefork というモジュールを自作して、たとえば Plack の Server::Standalone::Prefork とかで使っています。
で、まあ、prefork なサーバとか書いてると、(Min|Max)SpareServers 対応してないんすか? というのは FAQ なわけで。プロのサーバ管理者の間では存在価値が疑問視されて久しい (Min|Max)SpareServers だと思うんですが、まあ書いてみるのもいいかと思って Parallel::Prefork のディストリビューションに Parallel::Prefork::SpareWorkers という (Min|Max)SpareServers 対応のクラスを追加しました。
作った理由はもうひとつあって、応答がなくなったワーカーを自動的に kill したり、スコアボードで処理状況を可視化したり、とかそういったこともできたらいいかな、みたいな。
閑話休題。でまあ、ワーカープロセス群の状態を管理しようと思うとスコアボードが必要になります。これをどう実現するか。C なら mmap + lock-free algorithm による読み書き、とかが楽だと思うんですけど、XS (Perl の C 拡張) 書くの面倒だし。現状は、各プロセス毎に1バイトしか (lock なしで) 読み書きしないので、race condition は問題にならないんですが、処理状況の可視化とかやり始めると、競合のこと考えないといけないし、どうしようかな...
というのが、
複数のプロセスが単一のファイルを同時に read / write をする場合、それぞれのオペレーションはアトミックなんでしょうか? (on linux or unix)
Twitter / Kazuho Oku: 複数のプロセスが単一のファイルを同時に read / ...
と twitter で相談した背景。で、knu さんに、ずばり、
@kazuho POSIX.1-2008では、通常ファイルについてはread(2)/write(2)ともアトミックだとあります。
Twitter / Akinori MUSHA: @kazuho POSIX.1-2008では、通常フ ...
と教えていただきました。ありがとうございます (他に返答をいただいた方々もありがとうございます)。
もうちょっと古い判から引用しておくと、
I/O is intended to be atomic to ordinary files and pipes and FIFOs. Atomic means that all the bytes from a single operation that started out together end up together, without interleaving from other I/O operations.
read
というわけで、普通に read(2) / write(2) (perl では sysread / syswrite) を使ってスコアボードを作れば、ロックとか気にしなくてもいいみたい。
@kazuho read/writeがアトミックでも、意図したバイト数を一発でread/writeする方法はないのでは?例えば、signalで割り込まれたり、バッファが足りなかったりすると、途中でsystem callやめて実際のread/writeバイト数を返す仕様ですよね。
Twitter / Keiichi Koyama: @kazuho read/writeがアトミックでも ...
という指摘は一般論としてはその通りだと思いますが、各ワーカープロセスの書き込み位置が固定で複数ページにまたがることがないスコアボードのようなケースでは partial write は発生しないでしょうし、partial read になっちゃった場合は再試行すればいいよね、みたく思っています。
Twitter で反応いただいた方々、ありがとうございました。
- 65 http://japan.cnet.com/blog/kenn/2010/01/12/entry_27036420/
- 44 http://reader.livedoor.com/reader/
- 13 http://blog.nomadscafe.jp/2010/01/2010.html
- 12 http://japan.cnet.com/blog/kenn/2010/01/12/entry_27036420/?ref=rss
- 11 http://www.google.co.jp/reader/view/
- 9 http://d.hatena.ne.jp/
- 8 http://pipes.yahoo.com/pipes/pipe.info?_id=faa858a20082ef6d25ad27557e37e011
- 7 http://b.hatena.ne.jp/entrylist
- 7 http://twitter.com/
- 7 http://www.google.com/reader/view/
