Come faccio a sapere se un goroutine è fatto, senza bloccare?
-
20-09-2019 - |
Domanda
Tutti gli esempi che ho visto finora coinvolgono il blocco per ottenere il risultato (tramite l'operatore <-chan
).
Il mio approccio attuale consiste nel far passare un puntatore ad una struct:
type goresult struct {
result resultType;
finished bool;
}
che il goroutine scrive al termine. Poi si tratta di una semplice questione di controllo finished
ogni volta che conveniente. Hai alternative migliori?
Quello che sto davvero puntando è un sistema di segnale slot in stile Qt. Ho la sensazione la soluzione avrà un aspetto quasi banale (chan
s avere un sacco di potenziale inesplorato), ma io non sono ancora familiarità sufficiente con la lingua di capirlo.
Soluzione
È possibile utilizzare il modello "virgola, ok" (vedere la loro pagina su " efficace go "):
foo := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.
Altri suggerimenti
select permette di controllare più canali in una sola volta, di prendere un ramo casuale ( di quelli in cui la comunicazione è in attesa):
func main () {
for {
select {
case w := <- workchan:
go do_work(w)
case <- signalchan:
return
// default works here if no communication is available
default:
// do idle work
}
}
}
Per tutta la trasmissione e di ricezione espressioni nella dichiarazione "selezionare", le espressioni del canale vengono valutate, insieme a eventuali espressioni che appaiono sul lato destro della send espressioni, al fine top-to-bottom. Se una qualsiasi delle operazioni che possono procedere, si è scelto e la comunicazione corrispondente e dichiarazioni vengono valutate. Altrimenti, se c'è un caso di default, che esegue; In caso contrario, i blocchi di dichiarazione fino a quando una delle comunicazioni possono completa.
È anche possibile sbirciare il buffer del canale per vedere se contiene qualcosa utilizzando len:
if len(channel) > 0 {
// has data to receive
}
Questa non toccherà il buffer del canale, a differenza foo, gotValue := <- ch
che rimuove un valore quando gotValue == true
.