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

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


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


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.


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)


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


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.