2016-04-22 12 views
2

Ich bin neu in Fasern und EventMachine, und habe erst vor kurzem über Fasern herausgefunden, wenn ich sah, ob Ruby irgendwelche Nebenläufigkeitsfunktionen wie go-lang hatte.Wie erreicht man parallele Aufgaben mit Ruby's Fibers?

Es scheint nicht viele Beispiele für echte Anwendungsfälle für die Verwendung eines Fibers zu geben.

Ich habe es geschafft, diese zu finden: https://www.igvita.com/2009/05/13/fibers-cooperative-scheduling-in-ruby/ (ab 2009 zurück !!!)

, die den folgenden Code hat:

require 'eventmachine' 
require 'em-http' 
require 'fiber' 

def async_fetch(url) 
    f = Fiber.current 
    http = EventMachine::HttpRequest.new(url).get :timeout => 10 
    http.callback { f.resume(http) } 
    http.errback { f.resume(http) } 

    return Fiber.yield 
end 

EventMachine.run do 
    Fiber.new{ 
    puts "Setting up HTTP request #1" 
    data = async_fetch('http://www.google.com/') 
    puts "Fetched page #1: #{data.response_header.status}" 

    EventMachine.stop 
    }.resume 
end 

Und das ist toll, async Anfrage GET! Yay!!! aber ... wie benutze ich es eigentlich asynchron? Das Beispiel hat nichts anderes als das Erstellen der enthaltenen Fiber.

Von dem, was ich verstehe (und nicht verstehen):

async_fetch blockiert, bis f.resume genannt wird.

f ist die aktuelle Fiber, die die im EventMachine.run-Block erstellte Umbruch-Fiber ist.

Der async_fetch gibt den Steuerungsfluss an seinen Aufrufer zurück? Ich bin mir nicht sicher, was das tut

Warum hat die Umhüllung Faser am Ende wieder aufgenommen? Sind Fasern standardmäßig pausiert?

Außerhalb des Beispiels, wie verwende ich Fasern, um zu sagen, schießen eine Reihe von Anfragen ausgelöst durch Tastaturbefehle?

wie, zum Beispiel: jedes Mal, wenn ich einen Brief eintippe, stelle ich eine Anfrage an Google oder etwas? - Normalerweise erfordert dies einen Thread, den der Haupt-Thread dem parallelen Thread mitteilen würde, um einen Thread für jede Anfrage zu starten. : - \

Ich bin neu in Nebenläufigkeit/Fasern. Aber sie sind so faszinierend!

Wenn jemand diese Fragen beantworten kann, würde das sehr geschätzt werden !!!

Antwort

2

Es gibt eine Los der Verwirrung in Bezug auf Fasern in Ruby. Fasern sind kein Werkzeug, mit dem Nebenläufigkeit implementiert werden kann; Sie sind lediglich eine Art, den Code so zu organisieren, dass er klarer darstellt, was vor sich geht.

Dass der Name "Fasern" ähnlich wie "Fäden" meiner Meinung nach zu der Verwirrung beiträgt.

Wenn Sie echte Gleichzeitigkeit wollen, das heißt, die die CPU-Last auf alle verfügbaren CPU verteilen, haben Sie folgende Möglichkeiten:

In MRI Ruby-

Ausführen mehrerer Ruby-VMs (dh OS-Prozesse) mit fork usw. Auch bei mehreren Threads in Ruby verhindert die GIL (Global Interpreter Lock) die Verwendung von mehr als 1 CPU durch die Ruby Runtime.

In JRuby

Anders als MRI Ruby wird JRuby mehrere CPUs verwenden, wenn Threads zuweisen, so dass Sie wirklich eine gleichzeitige Verarbeitung erhalten.

Wenn Ihr Code die meiste Zeit damit verbringt, auf externe Ressourcen zu warten, benötigen Sie möglicherweise keinen echten gemeinsamen Zugriff. MRI-Threads oder irgendeine Art von Event-Handling-Schleife wird wahrscheinlich gut für Sie arbeiten.

+0

das ist sicherlich hilfreiche Informationen! Ich denke, jetzt muss ich nur herausfinden, ob ich Fäden brauche oder nicht. Ich benutze EventMachine in einem Projekt und benutze Benutzer Tastatureingabe - beim Drücken von Enter, könnten einige Anfragen passieren. Da alles in Ordnung ist und die meiste Zeit im Leerlauf ist, sagst du, dass es sich nicht lohnt, Threads zu verwenden? weil die Ausgeglichenheit alles angeht? – NullVoxPopuli

+0

Als Nebenbemerkung, nach dem Hype um Ruby 3x3 (Ruby 3.0 ist 3 mal schneller als Ruby 2.0), frage ich mich, ob MRI Ruby, wird in Zukunft mehrere CPUs verwenden. – NullVoxPopuli

+1

Ich habe diese Frage einmal an Matz bei einer RubyConf gestellt. Er sagte nein, der MRI-Ansatz zur Verwendung mehrerer CPUs startet mehrere Ruby-Prozesse. –