¿Cómo puedo saber si un goroutine se lleva a cabo, sin el bloqueo?
-
20-09-2019 - |
Pregunta
Todos los ejemplos que he visto hasta ahora implican la oclusión para obtener el resultado (a través del operador <-chan
).
Mi enfoque actual consiste en pasar un puntero a una estructura:
type goresult struct {
result resultType;
finished bool;
}
cual el goroutine escribe sobre la terminación. Entonces es una simple cuestión de comprobar finished
siempre conveniente. ¿Tiene mejores alternativas?
Lo que realmente estoy apuntando es un sistema de ranura señal al estilo de Qt. Tengo el presentimiento de la solución se verá casi trivial (chan
s tener lotes de potencial sin explorar), pero no estoy todavía lo suficientemente familiarizado con el lenguaje de averiguarlo.
Solución
Puede utilizar el patrón de "coma, ok" (ver su página en " efectiva ir "):
foo := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.
Otros consejos
Seleccione declaraciones le permite comprobar varios canales a la vez, teniendo una rama aleatorio ( de aquellos en los que la comunicación está en espera):
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
}
}
}
A pesar de la emisión y recepción expresiones en la instrucción "select", las expresiones de canal se evalúan, junto con las expresiones que aparecen en la parte derecha de envío expresiones, en orden de arriba a abajo. Si cualquiera de las operaciones resultantes pueden proceder, uno es elegido y la de comunicación correspondiente y Se evalúan las declaraciones. De otra manera, si hay un caso por defecto, que ejecuta; En caso contrario, los bloques de instrucciones hasta que una de las comunicaciones puede completa.
También puede echar un vistazo al buffer de canal para ver si contiene cualquier cosa mediante el uso de len:
if len(channel) > 0 {
// has data to receive
}
Esto no tocará la memoria intermedia del canal, a diferencia de foo, gotValue := <- ch
que elimina un valor cuando gotValue == true
.