【问题标题】:Alternative for spawning a process with 'fork' in jRuby?在 jRuby 中使用“fork”生成进程的替代方法?
【发布时间】:2012-08-05 17:19:16
【问题描述】:

在 MRI Ruby 中我可以这样做:

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

但是上面的代码不会在 jRuby 中运行,因为它不支持 'fork' 方法:

NotImplementedError: fork is not available on this platform

在 jRuby 中是否有任何替代解决方案?

谢谢。

【问题讨论】:

  • this question 的答案可能对您有用。
  • 谢谢,Spoon 看起来很有趣,但它并没有解决我的问题,因为它只是生成了一个外部进程而不共享当前线程的状态。实际上,我需要“子进程”是另一个 Ruby 解释器,子进程将共享当前线程的状态。
  • @Kelvin 的回答非常好。我认为可能值得问一下为什么要 fork()。 Fork() 是一个内置于基于 unix 的系统的系统调用。另一方面,Java 旨在在任何地方运行。如果您需要分叉,那么我建议 JRuby 对您来说是错误的 ruby​​ 实现。

标签: ruby jruby


【解决方案1】:

这是一个很好的问题,但不幸的是,如果您想要启动一个与父进程共享状态的新进程,那么我不相信 JVM 可以安全地给您想要的东西。那是因为分叉只复制当前正在运行的线程。例如,GC 线程不会被复制。你不想在没有 GC 的情况下运行 JVM。

使用 fork 的唯一半安全方式是之后立即执行。

Charles Nutter 在他的 blog 中首先说您可以使用 FFI 来分叉和执行,但随后提出了一个警告:

这种方式使用fork+exec最大的问题就是不能 保证在 fork 调用和 exec 调用之间*没有发生*。 例如,如果 JVM 决定进行 GC 或移动内存,您可以 在 JVM 进程级别发生致命崩溃。正因为如此,我不 建议在 JRuby 中通过 FFI 使用 fork + exec,即使它很漂亮 很酷。

我倾向于相信他的建议。

因此,fork 和 exec 会带来一些风险,但保留分叉的 JVM 是自找麻烦。

您应该认真考虑 Sergio 评论中建议的替代方案。

【讨论】:

    【解决方案2】:

    我找到了解决方案。我们可以使用 JRuby 中的内置库 FFI 来“模拟”MRI 中的 Process.fork。

    # 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
    

    更多细节:

    https://github.com/ffi/ffi

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

    【讨论】:

    • Charles Nutter 建议它是dangerous to fork using jruby,除非您要立即执行。执行 exec 会导致分叉的 JVM 退出,这就是它安全的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    • 2018-12-10
    相关资源
    最近更新 更多