Va bene lasciare un canale aperto?


161

Va bene lasciare un canale Go aperto per sempre (non chiudere mai il canale) se non controllo mai il suo stato? Porterà perdite di memoria? Il seguente codice è OK?

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

Risposte:


238

Va bene lasciare un canale Go aperto per sempre e non chiuderlo mai. Quando il canale non viene più utilizzato, verrà raccolto.

Si noti che è necessario chiudere un canale solo se il ricevitore sta cercando una chiusura. La chiusura del canale è un segnale di controllo sul canale che indica che non seguono più dati.

Domanda di progettazione: chiusura del canale


3
Non sono sicuro di essere d'accordo con la risposta del link. Ho avuto una perdita di memoria nella gamma da 2 GB. Non appena ho aggiunto la chiusura, il geyser è diventato un rivolo.
Richard

9
@Richard: leggi attentamente l'intero thread. L'autore di Go gce l'autore di gccgodire che closei canali non sono necessari, a meno che tu non stia cercando un close. Questo è un consiglio autorevole.
peterSO,

6
@peterSO, potrebbe essere, ma so cosa ho visto ed è quello che ho segnalato, quindi per favore non licenziarmi.
Richard,

1
Bene, se hai un canale bufferizzato, l'aggiunta di messaggi ad esso dovrebbe usare la memoria. Tuttavia, se il tuo canale non è bufferizzato o non viene aggiunto nulla, l'utilizzo della memoria non aumenterà.
Metakeule,


31

Sì, è ok tenere aperto un canale. Comediceva il libro del linguaggio di programmazione go :

Non è necessario chiudere tutti i canali al termine. È necessario chiudere un canale solo quando è importante dire alle goroutine di ricezione che tutti i dati sono stati inviati. Un canale che il Garbage Collector ritiene irraggiungibile avrà le sue risorse recuperate indipendentemente dal fatto che sia chiuso o meno. (Non confonderlo con l'operazione di chiusura per i file aperti. Al termine, è importante chiamare il metodo Close su ogni file.)


7

Sì, è OK lasciare aperto il canale, e in effetti è tipico. Un canale in fase di apertura non costituisce un riferimento all'oggetto canale, quindi non impedisce che venga raccolto.


1

" Un principio generale dell'utilizzo dei canali Go è di non chiudere un canale dal lato destinatario e non chiudere un canale se il canale ha più mittenti simultanei. "

Come indicato chiaramente nella risposta sopra che ogni canale verrà GCed alla fine una volta contrassegnato per la pulizia, quindi va bene lasciare il canale non chiuso, l'unica differenza che farà sarà che quel canale sarà disponibile per gc dopo alcuni cicli, forse se non chiuso esplicitamente.

Anche i seguenti articoli questo e questo mostrano vari modi per chiudere un canale in caso di 1: N, N: 1 o M: N (mittenti: destinatari)


-5

Go è la spazzatura raccolta, quindi non devi davvero "liberare" nulla.

C'è la possibilità di chiudere i canali, ma è principalmente usato come - chiudi (canale) - dice alla goroutine (o al programma principale) che nient'altro verrà inviato su quel canale.


8
AFAIK anche in un linguaggio di immondizia un programmatore è ancora responsabile della liberazione di risorse non gestite, ad esempio chiusura di file, socket e così via. Devo chiudere il canale come un file?
Kluyg,

3
@Kluyg La risposta è no. Stai parlando di risorse del sistema operativo (quali canali non lo sono). Dipende da una risorsa e una lingua, ma di solito si consiglia di chiudere manualmente le risorse del sistema operativo non perché GC non lo farebbe, ma piuttosto perché non è deterministico. Il gotcha correlato più comune è un errore di troppi file aperti . Continui ad aprire i file ... Ti aspetti che GC lo faccia ... Non esaurisci la memoria (quindi GC non si avvia) ... A corto di descrittori di file a livello di sistema operativo. Il sistema operativo
interrompe

Sono confuso sul perché questo abbia ottenuto così tanti voti negativi mentre era corretto tutto il tempo e afferma lo stesso di altre risposte accettate ...
eja
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.