5

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

ただし、上記のコードは「fork」メソッドをサポートしていないため、jRuby では実行されません。

NotImplementedError: fork is not available on this platform

jRubyでこれに対する代替ソリューションはありますか?

ありがとう。

4

2 に答える 2

7

これは良い質問ですが、残念ながら、親プロセスと状態を共有する新しいプロセスを開始することが必要な場合、JVM が安全に必要なものを提供できるとは思えません。これは、フォークは現在実行中のスレッドのみをコピーするためです。たとえば、GC スレッドはコピーされません。GC なしで JVM を実行したくありません。

fork を使用する唯一の半安全な方法は、直後に実行することです。

Charles Nutter は彼のブログで、FFI を使用して fork と exec を実行できると最初に述べていますが、次に注意事項を示しています。

このように fork+exec を使用する際の最大の問題は、fork 呼び出しと exec 呼び出しの間で *何も*起こらないことを保証できないことです。たとえば、JVM が GC またはメモリの移動を決定した場合、JVM プロセス レベルで致命的なクラッシュが発生する可能性があります。そのため、JRuby で FFI を介して fork + exec を使用することはお勧めしません。

私はここで彼のアドバイスを信頼する傾向があります.

したがって、フォークと実行にはある程度のリスクが伴いますが、フォークされた JVM を維持することは問題を引き起こします。

Sergio のコメントで提案された代替案を真剣に検討する必要があります。

于 2012-11-09T23:39:04.350 に答える
1

私はこれに対する解決策を見つけました。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

于 2012-09-12T03:01:25.177 に答える