2014-07-27 2 views
6

Ich konnte keine detaillierte Dokumentation über die @async Makro finden. Aus den Dokumenten über Parallelismus verstehe ich, dass es nur einen System-Thread innerhalb eines Julia-Prozesses gibt und dass explizite Task-Umschaltung mit Hilfe der yieldto-Funktion stattfindet - korrigiere mich, wenn ich falsch liege.Julia: Verständnis, wenn Taskwechsel passiert

Für mich ist es schwierig zu verstehen, wann genau diese Aufgabenwechsel nur durch den Blick auf den Code passieren, und zu wissen, wann es passiert, scheint entscheidend.

Wie ich ein yieldto irgendwo in dem Code (oder in einer Funktion durch den Code genannt) muss da sein, um sicherzustellen, dass das System nicht mit nur einer Aufgabe fest ist.

Zum Beispiel, wenn es ein read Betrieb, innerhalb dem es wahrscheinlich lesen, ist ein wait Aufruf und bei der Umsetzung von wait gibt es wahrscheinlich einen yieldto Anruf. Ich dachte, dass ohne den yieldto Anruf der Code in einer Aufgabe stecken würde; Das folgende Beispiel scheint jedoch zu beweisen, dass diese Hypothese falsch ist.

@async begin # Task A 
    while true 
     println("A") 
    end  
end 

while true # Task B 
    println("B") 
end 

Dieser Code erzeugt die folgende Ausgabe

BA 
BA 
BA 
... 

Es ist mir sehr unklar, wo der Task-Wechsel in der Aufgabe durch die @async Makro in dem obigen Code erstellt geschieht.

Wie kann ich feststellen, dass ich bei einem Code die Punkte sehe, an denen eine Taskwechsel stattfindet?

Antwort

4

Der Taskwechsel erfolgt innerhalb des Anrufs an println("A"), die an einem bestimmten Punkt ruft write(STDOUT, "A".data). Da isa(STDOUT, Base.AsyncStream) und es gibt keine Methode, die mehr spezialisiert ist, dies wird aufgelöst zu:

write{T}(s::AsyncStream,a::Array{T}) at stream.jl:782 

Wenn Sie bei dieser Methode betrachten, werden Sie feststellen, dass es stream_wait(ct) auf die aktuelle Aufgabe ruft ct, die wiederum wait() nennt.

(Beachten Sie auch, dass println nicht atomar ist, weil es ein Potential wait ist es, die Argumente und die Neue-Zeile zwischen dem Schreiben.)

Sie könnten natürlich auch bestimmen, wann Sachen wie das von bei alle der Code suchen geschieht beteiligt. Aber ich verstehe nicht, warum Sie das genau wissen müssten, denn wenn Sie mit Parallelität arbeiten, sollten Sie sich nicht auf Prozesse verlassen, die den Kontext wechseln. Wenn Sie von einer bestimmten Ausführungsreihenfolge abhängig sind, synchronisieren Sie explizit.

(Sie haben dies bereits in Ihrer Frage notiert, aber lassen Sie es mich hier wiederholen: Als Faustregel gilt, dass Sie beim Einsatz von grünen Threads bei I/O potentielle Kontextwechsel erwarten, da das Blockieren für IO ein Lehrbuch ist Beispiel dafür, warum grüne Fäden in erster Linie nützlich sind.)