@kyanny's blog

My thoughts, my life. Views/opinions are my own.

Ruby 2.2.0 の vfork

Ruby 2.2.0 のリリースノートを読んでいて system() と spawn() における vfork(2) の使用を実験的にサポートしました というのが目に止まったので手元で動作確認してみた。

以下の Linux 環境で実験した。

vagrant@precise32:~$ uname -a
Linux precise32 3.2.0-23-generic-pae #36-Ubuntu SMP Tue Apr 10 22:19:09 UTC 2012 i686 i686 i386 GNU/Linux

Ruby 2.2.0 ではたしかにシステムコール一覧に vfork がでてきた。

vagrant@precise32:~$ ruby2.2.0/bin/ruby -v
ruby 2.2.0p0 (2014-12-25 revision 49005) [i686-linux]
vagrant@precise32:~$ strace -c ruby2.2.0/bin/ruby -e 'system("true")'   

では Ruby 2.1.5 では fork がでてくるのかと思いきや、 fork(2) ではなく clone(2) という似ているが別のシステムコールを使うようだ。

vagrant@precise32:~$ ruby2.1.5/bin/ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [i686-linux]
vagrant@precise32:~$ strace -c ruby2.1.5/bin/ruby -e 'system("true")' 

(Ruby 2.2.0 でも clone システムコールは一回呼ばれているが、 Ruby 2.1.5 だと二回呼ばれているので、一回多いのが vfork のかわりということだろう)

しかし同じ実験を Mac OSX 上でやってみると、 Ruby 2.2.0 でも vfork が呼ばれている形跡がない。検索してみると、 OSX ではうまく動作しないため無効になっているようだ。

$ uname -a
Darwin Kensukes-MacBook-Pro.local 14.0.0 Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64

http://d.hatena.ne.jp/nagachika/20140907

http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=47441&view=revision

https://github.com/ruby/ruby/blob/trunk/configure.in#L1008

$ ruby -v
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14]
$ sudo dtruss -c ruby -e 'system("true")'

$ ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin14.0]
$ sudo dtruss -c ruby -e 'system("true")'

ところで Mac OSX 上で実験した結果をみると fork(2) も clone(2) も呼ばれていないように見えるが、いったいどのシステムコールで外部プロセスを起動しているんだろう?