¿Está bien dejar un canal abierto?

161

¿Está bien dejar un canal Go abierto para siempre (nunca cierre el canal) si nunca verifico su estado? ¿Conducirá a pérdidas de memoria? ¿Está bien el siguiente código?

func (requestCh chan<- Request) GetResponse(data RequestData) Response {
    reply := make(chan Response)
    requestCh <- Request{data: data, replyCh: reply}
    return <-reply
}
Kluyg
fuente

Respuestas:

238

Está bien dejar un canal Go abierto para siempre y nunca cerrarlo. Cuando el canal ya no se use, se recolectará basura.

Tenga en cuenta que solo es necesario cerrar un canal si el receptor está buscando un cierre. Cerrar el canal es una señal de control en el canal que indica que no hay más datos a continuación.

Pregunta de diseño: cierre de canales

PeterSO
fuente
3
No estoy seguro de estar de acuerdo con la respuesta del enlace. Tuve una pérdida de memoria en el rango de 2GB. Tan pronto como agregué el cierre, el géiser se convirtió en un goteo.
Richard
9
@ Richard: Lea todo el hilo cuidadosamente. El autor de Go gcy el autor de gccgodichos canales closeno son necesarios, a menos que esté buscando un close. Eso es un consejo autorizado.
peterSO
66
@peterSO, eso puede ser, pero sé lo que vi y eso es lo que informé, así que no me descarten.
Richard
1
Bueno, si tiene un canal almacenado en el búfer, agregarle mensajes debería usar memoria. Sin embargo, si su canal no está almacenado o no se agrega nada, el uso de memoria no aumentará.
metakeule
¿Qué pasa con esto entonces: groups.google.com/forum/#!topic/golang-nuts/bfuwmhbZHYw ?
Kamil Dziedzic
31

Sí, está bien mantener un canal abierto. Como dice el libro del lenguaje de programación :

No necesita cerrar todos los canales cuando haya terminado. Solo es necesario cerrar un canal cuando es importante informar a las gorutinas receptoras que se han enviado todos los datos. Un canal que el recolector de basura determine como inalcanzable tendrá sus recursos reclamados si está cerrado o no. (No confunda esto con la operación de cierre para abrir archivos. Es importante llamar al método Cerrar en cada archivo cuando haya terminado con él).

cizixs
fuente
7

Sí, está bien dejar el canal abierto, y de hecho es típico. Un canal abierto no constituye una referencia al objeto del canal, por lo que no evita que se recolecte basura.

Sonia
fuente
1

" Un principio general del uso de canales Go es no cerrar un canal desde el lado del receptor y no cerrar un canal si el canal tiene múltiples remitentes concurrentes " .

Como se mencionó claramente en la respuesta anterior, cada canal será GCed eventualmente una vez que esté marcado para la limpieza, por lo que está bien dejar el canal sin cerrar, la única diferencia que hará es que ese canal estará disponible gcdespués de algunos ciclos, tal vez si no cerrado explícitamente

También los artículos siguientes de este y esta muestra varias formas de cerrar un canal en el caso de 1: N, N: 1 o M: N (emisores: receptores)

Abhishek Srivastava
fuente
-5

Ir es basura recolectada, por lo que realmente no tienes que 'liberar' nada.

Existe la posibilidad de cerrar canales, pero se usa principalmente como - cerrar (canal) - decirle a la rutina (o programa principal) que no se enviará nada más en ese canal.

Łukasz Gruner
fuente
8
AFAIK, incluso en un lenguaje de recolección de basura, un programador sigue siendo responsable de liberar recursos no administrados, por ejemplo, cerrar archivos, sockets y demás. ¿Necesito cerrar el canal como un archivo?
Kluyg
3
@Kluyg La respuesta es no. Estás hablando de recursos del sistema operativo (qué canales no son). Depende de un recurso y un idioma, pero generalmente se recomienda cerrar los recursos del sistema operativo manualmente no porque GC no lo haga, sino porque no es determinista. El gotcha relacionado más común es demasiados errores de archivos abiertos . Sigue abriendo archivos ... Espera que GC lo haga ... No se queda sin memoria (por lo tanto, GC no se activa) ... Se queda sin descriptores de archivo en el nivel del sistema operativo. OS mata el proceso :)
Pijusn
Estoy confundido acerca de por qué esto obtuvo tantos votos negativos mientras fue correcto todo el tiempo y dice lo mismo que otras respuestas aceptadas ...
Eja