¿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
}

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


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


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


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.


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)


-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.


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.