2014-07-27 12 views
6

Nie można znaleźć szczegółowej dokumentacji dotyczącej makra @async. Z dokumentacji o paralelizmie rozumiem, że istnieje tylko jeden wątek systemowy używany w procesie Julii i istnieje jawne przełączanie zadań za pomocą funkcji yieldto - popraw mnie, jeśli się mylę.Julia: zrozumienie, kiedy następuje przełączanie zadań

Dla mnie trudno jest zrozumieć, kiedy dokładnie te przełączniki mają miejsce, po prostu patrząc na kod, a wiedza, kiedy to się wydarzy, wydaje się kluczowa.

Jak rozumiem yieldto gdzieś w kodzie (lub w jakiejś funkcji wywoływanej przez kod) musi tam być, aby upewnić się, że system nie utknął tylko z jednym zadaniem.

Na przykład, gdy nie jest to operacja read wewnątrz czytać prawdopodobnie istnieje wait wezwanie i we wdrażaniu wait prawdopodobnie istnieje yieldto wezwanie. Myślałem, że bez wywołania yieldto kod utknąłby w jednym zadaniu; jednak uruchomienie następującego przykładu zdaje się potwierdzać tę hipotezę jako niewłaściwą.

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

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

Ten kod daje następujący wynik

BA 
BA 
BA 
... 

To bardzo dla mnie jasne, gdzie przełączanie zadanie dzieje wewnątrz zadania utworzonego przez @async makra w powyższym kodzie.

Jak mogę powiedzieć o przejrzeniu niektórych kodów punktów, w których następuje przełączanie zadań?

Odpowiedz

4

Przełącznik zadań pojawia się wewnątrz połączenia pod numerem println("A"), który w pewnym momencie wywołuje write(STDOUT, "A".data). Ponieważ isa(STDOUT, Base.AsyncStream) i nie ma metody, która jest bardziej wyspecjalizowany, ten postanawia:

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

Jeśli spojrzeć na tej metodzie, można zauważyć, że wywołuje ona stream_wait(ct) na bieżącym zadaniu ct, co z kolei wywołuje wait().

(również pamiętać, że println nie jest atomowy, gdyż istnieje potencjalne wait między piśmie argumenty i przełamane.)

Można oczywiście określić, kiedy takie rzeczy się dzieje, patrząc na wszystkich: kod zaangażowany. Ale nie rozumiem, dlaczego musiałbyś to dokładnie znać, ponieważ podczas pracy z paralelizmem nie powinieneś polegać na przetwarzaniu kontekstu. Jeśli zależy Ci na określonej kolejności wykonywania, zsynchronizuj jawnie.

(Zauważyłeś już to w swoim pytaniu, ale pozwól mi to powtórzyć tutaj: Jako regułę, przy używaniu zielonych nici, możesz oczekiwać potencjalnych przełączników kontekstu podczas wykonywania IO, ponieważ blokowanie dla IO jest podręcznikiem przykład dlaczego zielone nici są użyteczne w pierwszej kolejności.)