Alternative for spawning a process with 'fork' in jRuby?

喜欢而已 提交于 2020-01-24 04:36:09

问题


In MRI Ruby I can do this:

def transfer
  internal_server = self.init_server
  pid = fork do
    internal_server.run
  end

  # Make the server process run independently.
  Process.detach(pid)

  internal_client = self.init_client
  # Do other stuff with connecting to internal_server...
  internal_client.post('some data')    
ensure
  # Kill server
  Process.kill('KILL', pid) if pid
end

However the above code will not run in jRuby, because it does not support 'fork' method:

NotImplementedError: fork is not available on this platform

Is there any alternative solution for this in jRuby?

Thanks.


回答1:


This is a good question, but unfortunately I don't believe the JVM can safely give you what you want, if what you want is to start a new process that shares state with the parent process. That's because forking only copies the currently running thread. GC thread(s) for example, aren't copied. You don't want to be running a JVM without GC.

The only semi-safe way of using fork is to exec immediately afterwards.

Charles Nutter, on his blog, first says you can use FFI to fork and exec, but then provides a caveat:

The biggest problem with using fork+exec in this way is that you can't guarantee *nothing* happens between the fork call and the exec call. If, for example, the JVM decides to GC or move memory around, you can have a fatal crash at the JVM process level. Because of that, I don't recommend using fork + exec via FFI in JRuby, even though it's pretty cool.

I would tend to trust his advice here.

So, a fork and exec carries some risk, but keeping the forked JVM around is asking for trouble.

You should seriously consider the alternatives suggested by Sergio's comment.




回答2:


I found out the solution for this. We can use the built-in library FFI in JRuby to 'simulate' the Process.fork in MRI.

# To mimic the Process.fork in MRI Ruby
module JRubyProcess
  require 'ffi'
  extend FFI::Library
  ffi_lib FFI::Library::LIBC
  attach_function :fork, [], :int
end

pid = JRubyProcess.fork do
  #internal_server.run
end

More details:

https://github.com/ffi/ffi

http://blog.headius.com/2008/10/ffi-for-ruby-now-available.html



来源:https://stackoverflow.com/questions/11818463/alternative-for-spawning-a-process-with-fork-in-jruby

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!