2005年04月27日

Rubyでの排他制御

サーバアプリケーションを開発する場合、避けて通れないのが排他制御。
Rubyにはいくつかの方法が準備してある。まず、File#flock。これは、UNIX系のOSで標準のflock(2)そのもの。
実際にSOAPのサーバで使ってみたが、これはうまく動かない。何故なら、File#flockは、プロセスに対して動くものだから。soap4rのサーバは、Rubyスレッドで実現されているので、多数のスレッドを起動しても、プロセスとしては一つだけ。File#flockであるスレッドPがロックをかけた後、別のスレッドQがロックをかけると、プロセスの実行がそこでブロックされてしまう。ということはスレッドQだけでなく、スレッドPも停止状態になってしまうということ。別の言葉で言うと、File#flockはスレッドセーフではない。
Soap4rのサーバがスレッドを利用しているのなら、スレッドセーフな排他制御を使えばよいわけだ。最もポピュラーなのは、Mutexを使うことだろう。
今回の実装も、これを使うことにした。 投稿者 fujino : 2005年04月27日 02:48 | トラックバック
コメント

一般には、サーバアプリケーションがwebrick(+ soap4rのsoaplet.rb)で閉じている場合、application scopeなサーバでなく、request scopeなサーバとすることで、問題が解決することもありますね(sample/soap/scopesample/server.rb)。

RAAなどはオブジェクトサーバを別プロセスにし、そことの間をDRbで通信、オブジェクトサーバの内部で必要な箇所を排他制御しています。

Posted by: nahi : 2005年05月05日 18:16

あ、sorp4rのエラい人、nahiさん直々の回答、ありがとうございます。
なるほど、プロセスをわける方法も用意されているんですね。今回の用途を考えると、サーバプロセス以外にもメンテナンスで同じファイルを触る可能性があるので、flockを使った方がいいんだけどなぁ、と思っていたところです。試しにflockバージョンを作ってみたいと思います。

Posted by: fujino : 2005年05月09日 13:16

あ、sorp4rのエラい人、nahiさん直々の回答、ありがとうございます。
なるほど、プロセスをわける方法も用意されているんですね。今回の用途を考えると、サーバプロセス以外にもメンテナンスで同じファイルを触る可能性があるので、flockを使った方がいいんだけどなぁ、と思っていたところです。試しにflockバージョンを作ってみたいと思います。

Posted by: fujino : 2005年05月09日 13:17

あ、いえ、プロセスを分ける方法ではなく、リクエスト毎にサーバントオブジェクトを個別生成するか、もしくは1つのオブジェクトを各リクエストで共有するか、の違いです。スレッド/プロセスとは関係ありません。

共有資源がサーバントオブジェクトの中のみにできるのであれば、上記方法でなんとかなりますが、ファイルなど、外部リソースを共有する場合は、やはり別の方法が必要になります。

Posted by: nahi : 2005年05月11日 12:00
コメントする









名前、アドレスを登録しますか?