2012-08-05 11 views
5

In MRI Rubin kann ich dies tun:Alternative zum Abrufen eines Prozesses mit 'Gabel' in jRuby?

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 

jedoch der obige Code wird nicht in JRuby laufen, weil es nicht 'fork' Methode unterstützt:

NotImplementedError: fork is not available on this platform 

Gibt es eine alternative Lösung für Das in jRuby?

Danke.

+1

Antworten auf [diese Frage] (http://stackoverflow.com/questions/5349629/ruby-daemons-and-jruby-alternative-options) könnten für Sie nützlich sein. –

+0

Danke, [Löffel] (https://github.com/headius/spoon) scheint interessant, aber es löst mein Problem nicht, weil es nur einen externen Prozess hervorbringt, ohne den Zustand des aktuellen Threads zu teilen. Eigentlich brauche ich 'Kind-Prozess' ist ein anderer Ruby-Interpreter und der Child-Prozess teilt den Status des aktuellen Threads. –

+0

@ Kelvins Antwort ist wirklich gut. Ich denke, es könnte sich lohnen zu fragen, warum Sie fork() wollen. Fork() ist ein Systemaufruf, der in Unix-basierten Systemen integriert ist. Java dagegen soll überall laufen. Wenn Sie eine Gabelung benötigen, würde ich vorschlagen, dass JRuby die falsche Ruby-Implementierung für Sie ist. – Stewart

Antwort

1

Ich fand die Lösung dafür. Wir können die integrierte Bibliothek FFI in JRuby verwenden, um die Process.fork in MRI 'zu simulieren'.

# 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 

Weitere Details:

https://github.com/ffi/ffi

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

+1

Charles Nutter schlägt vor, dass es [gefährlich ist, mit jruby zu verzweigen] (https://github.com/jruby/jruby/issues/246), es sei denn, Sie werden sofort exec.Wenn Sie exec ausführen, wird die gegabelte JVM beendet, weshalb sie sicher ist. – Kelvin

7

Dies ist eine gute Frage, aber leider glaube ich nicht, die JVM können Sie sicher, was Sie wollen, wenn das, was Sie Wollen Sie einen neuen Prozess starten, der den Status mit dem übergeordneten Prozess teilt. Das liegt daran, dass Forking nur den aktuell laufenden Thread kopiert. GC-Threads zum Beispiel werden nicht kopiert. Sie möchten keine JVM ohne GC ausführen.

Die einzige halbwegs sichere Art der Verwendung von fork ist die sofortige Ausführung.

Charles Nutter, auf seinem blog, sagt Zuerst kann man FFI verwenden, um fork und exec, sondern liefert dann eine Einschränkung:

Das größte Problem bei der Verwendung von fork + exec auf diese Weise ist, dass man‘ t garantie * nichts * passiert zwischen dem fork call und dem exec call. Wenn die JVM z. B. beschließt, GC zu speichern oder Speicher zu verschieben, kann auf der JVM-Prozessebene einen schwerwiegenden Absturz verursachen. Aus diesem Grund, ich nicht empfehle die Verwendung von Gabel + Exec über FFI in JRuby, obwohl es ziemlich cool ist.

Ich würde dazu neigen, seinen Rat hier zu vertrauen.

Also, eine Gabel und exec trägt ein gewisses Risiko, aber die gegabelte JVM herum zu halten verlangt nach Ärger.

Sie sollten ernsthaft die Alternativen in Betracht ziehen, die von Sergios Kommentar vorgeschlagen wurden.

Verwandte Themen