É permitido deixar um canal aberto?

161

Não há problema em deixar um canal Go aberto para sempre (nunca feche o canal) se eu nunca verificar seu estado? Isso levará a vazamentos de memória? O código a seguir está OK?

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

Respostas:

237

Não há problema em deixar um canal Go aberto para sempre e nunca fechá-lo. Quando o canal não for mais usado, ele será coletado como lixo.

Note que só é necessário fechar um canal se o receptor estiver procurando por um fechamento. Fechar o canal é um sinal de controle no canal, indicando que não há mais dados a seguir.

Pergunta de design: fechamento de canal

peterSO
fonte
3
Não tenho certeza se concordo com a resposta do link. Eu tive um vazamento de memória na faixa de 2 GB. Assim que adicionei o fechamento, o gêiser se tornou um filete.
Richard
9
@ Richard: Leia todo o tópico com atenção. O autor do Go gce o autor do gccgodigamos channel closes não são necessários, a menos que você esteja procurando um close. Esse é um conselho autoritário.
PeterSO
6
@ PeterSO, isso pode ser, mas eu sei o que vi e foi isso que relatei, por isso não me demitam.
Richard
1
Bem, se você possui um canal em buffer, adicionar mensagens a ele deve usar memória. No entanto, se o seu canal não estiver em buffer ou se nada for adicionado, o uso da memória não aumentará.
metakeule
31

Sim, não há problema em manter um canal aberto. Como o livro de linguagem de programação go declarou:

Você não precisa fechar todos os canais quando terminar. Só é necessário fechar um canal quando é importante informar às goroutines receptoras que todos os dados foram enviados. Um canal que o coletor de lixo determine como inacessível terá seus recursos recuperados, independentemente de estar ou não fechado. (Não confunda isso com a operação de fechamento de arquivos abertos. É importante chamar o método Close em todos os arquivos quando terminar.)

cizixs
fonte
7

Sim, não há problema em deixar o canal aberto e, de fato, é típico. Um canal aberto não constitui uma referência ao objeto do canal e, portanto, não impede que seja coletado como lixo.

Sonia
fonte
1

" Um princípio geral do uso de canais Go é não fechar um canal do lado do receptor e não fechar um canal se o canal tiver vários remetentes simultâneos " .

Como mencionado claramente na resposta acima, como todos os canais serão GCed eventualmente depois de marcados para limpeza, não há problema em deixar o canal não fechado. A única diferença que fará é que esse canal estará disponível por gcalguns ciclos, talvez se não fechado explicitamente.

Também os seguintes artigos esta e esta mostra várias maneiras para fechar um canal em caso de 1: N, N: 1 ou H: N (remetentes: receptores)

Abhishek Srivastava
fonte
-5

Go é lixo coletado, para que você realmente não precise "libertar" nada.

Existe a possibilidade de fechar canais, mas é usado principalmente como - close (canal) - diz à goroutine (ou programa principal) que nada mais será enviado nesse canal.

Łukasz Gruner
fonte
8
AFAIK, mesmo em uma linguagem de coleta de lixo, um programador ainda é responsável por liberar recursos não gerenciados, por exemplo, fechar arquivos, soquetes e assim por diante. Preciso fechar o canal como um arquivo?
precisa saber é o seguinte
3
@Kluyg A resposta é não. Você está falando sobre recursos do SO (quais canais não são). Depende de um recurso e idioma, mas geralmente é recomendável fechar os recursos do SO manualmente, não porque o GC não faria isso, mas porque não é determinístico. A pegadinha relacionada mais comum é o erro de muitos arquivos abertos . Você continua abrindo arquivos ... Você espera que o GC faça isso ... Você não fica sem memória (portanto, o GC não entra em ação) ... Você fica sem descritores de arquivos no nível do sistema operacional. OS mata o processo :)
Pijusn
Estou confuso sobre o motivo de ter recebido tantos votos negativos enquanto estava correto o tempo todo e afirma o mesmo que outras respostas aceitas ...
eja 16/04