2014-04-22 7 views
7

Ich habe versucht, zwei Aufgaben (Koroutinen) zu kooperieren, aber ohne Erfolg. Unten ist was ich habe. Ich sehe nie die Printlns von Source- oder Sink-Funktionen, und der wait() - Aufruf scheint für immer zu hängen. Ich habe auch versucht, die p (source) -Aufgabe zu einer globalen Variable zu machen, anstatt sie als Argument an sink() zu übergeben, aber das scheint auch nicht zu funktionieren (selbst wenn ich es innerhalb von sinke() als global deklariere.Julia: Übergabe von Daten zwischen Coroutinen (Aufgaben)

Diese

ist die Art von Dingen, die ich entdeckte, was ich tun kann sehr leicht mit den Kanälen und goroutines in Go.

ich habe auch mit Aufruf yieldto() innerhalb der Quelle() und Waschbecken() Funktionen experimentiert, aber ich noch scheinen in einer Sackgasse zu enden.

jeder, der ein Beispiel von mehreren Aufgaben Daten in irgendeiner Art und Weise zu teilen? Idealerweise weise~~POS=HEADCOMP würde ich eine Pipeline haben oder lange Kette von Aufgaben.

Vielen Dank im Voraus für Ihre Hilfe.

println("Hello") 

function source() 
    println("source start") 
    produce("start") 
    produce("stop") 
end 

function sink(p::Task) 
    println("sink start") 
    println(consume(p)) 
    println(consume(p)) 
end 


a = Task(source) 
b = Task(() -> sink(a) ) 

wait(b) 
wait(a) 

println("Goodbye") 

Antwort

7

In Julia wird die Aufgabe beim Erstellen einer Aufgabe nicht automatisch geplant. Die Wartefunktion plant auch nicht, sodass Sie mit einem Deadlock enden. Dies ist ein großer Unterschied zu Go, bei dem die go-Anweisung die gesamte Planung für Sie übernimmt. In Julia musst du ein bisschen mehr arbeiten. Verwenden Sie speziell die Makros @sync und @async, um einfacher zu machen.

@sync begin # @sync will wait for all the contained tasks to terminate. 
    a = @async source() # @async will create and schedule a task for you automatically 
    @async sink(a) 
end 

Sie werden feststellen, dass dies auch nicht beendet wird. Alle Drucke werden ausgeführt, aber die Aufgabe wird nicht beendet. Die Ursache ist, dass @sync auf den Abschluss von Task a wartet, während Task a nicht geplant wurde. Fügen Sie Ihrer Ableitungsfunktion einen endgültigen Verbrauch oder Zeitplan hinzu, um Aufgabe a zu erzwingen, dass sie ein letztes Mal geplant wird, damit sie beendet werden kann. Oder besser noch verwenden Sie eine for-Schleife für die Aufgabe, so dass Sie immer erschöpft sind.

println("Hello") 

function source() 
    println("source start") 
    produce("start") 
    produce("stop") 
    println("source end") 
end 

function sink(p::Task) 
    println("sink start") 
    for s in p 
    println(s) 
    end 
    println("sink end") 
end 

@sync begin 
    a = @async source() 
    @async sink(a) 
end 

println("Goodbye") 

Julias Aufgaben sind kooperativ geplant, was im Grunde bedeutet, dass Sie sicherstellen müssen, dass jede Aufgabe von Ihnen selbst geplant wird. Die Laufzeit wird es nicht für Sie tun. Glücklicherweise machen die Makros @sync und @async das meiste für Sie.

+0

Großartig! Danke für die klare Antwort. Ich kann sehen, dass Julia viel feinkörniger Kontrolle über Koroutinen gibt. Ich schätze Ihre Hilfe. –