2014-04-22 7 views
7

Ho provato a ottenere due compiti (coroutine) per collaborare, ma senza risultato. Di seguito è quello che ho. Non vedo mai i valori di stampa dalle funzioni source o sink e la chiamata wait() sembra bloccarsi per sempre. Ho anche provato a rendere l'attività p (source) una variabile globale, invece di passarla a sink() come argomento, ma non sembra funzionare neanche (anche quando la dichiaro all'interno di sinke() come globale.Julia: passaggio di dati tra coroutine (attività)

Questo è il tipo di cosa che ho scoperto che posso fare molto facilmente con canali e goroutines a Go.

ho anche sperimentato con chiamando yieldto() all'interno della sorgente() e lavandino() funzioni, ma io sembrano ancora finire in stallo.

Chiunque con un esempio di più attività di condivisione dei dati in qualche modo? Idealmente, avrei un oleodotto o lunga catena di attività.

Grazie in anticipo per il vostro aiuto.

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") 

risposta

7

In Julia, la creazione di un'attività non pianifica automaticamente tale attività. La funzione di attesa non è pianificata, quindi si finisce con un deadlock. Questa è una grande differenza rispetto a Go, dove l'istruzione go si prende cura di tutte le pianificazioni per te. A julia devi fare un po 'più di lavoro. In particolare, usa i macro @sync e @async per rendere più facile.

@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 

Si noterà che anche questo non termina. Tutte le stampe si verificano ma l'attività non termina. La causa è @sync in attesa del completamento dell'operazione, ma l'attività a non è stata pianificata. Aggiungi un consumo finale o una pianificazione alla funzione sink per forzare l'attività a essere pianificata un'ultima volta in modo che possa terminare. O meglio ancora usa un ciclo for sull'attività in modo che tu la esaurisca sempre.

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") 

I compiti di Julia sono pianificati in modo cooperativo, il che significa che è necessario garantire che ogni attività venga pianificata da solo. Il runtime non lo farà per te. Fortunatamente le macro @sync e @async fanno la maggior parte di questo per te.

+0

Ottimo! Grazie per la risposta chiara. Vedo che Julia dà un controllo molto più fine sulle coroutine. Apprezzo il vostro aiuto. –