Est-il acceptable de laisser une chaîne ouverte?


161

Puis-je laisser un canal Go ouvert pour toujours (ne jamais fermer le canal) si je ne vérifie jamais son état? Cela conduira-t-il à des fuites de mémoire? Le code suivant est-il OK?

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

Réponses:


238

Il est normal de laisser un canal Go ouvert pour toujours et de ne jamais le fermer. Lorsque le canal n'est plus utilisé, il sera récupéré.

Notez qu'il n'est nécessaire de fermer un canal que si le récepteur recherche une fermeture. La fermeture du canal est un signal de commande sur le canal indiquant que plus aucune donnée ne suit.

Question de conception: fermeture de canal


3
Je ne suis pas sûr d'être d'accord avec la réponse du lien. J'ai eu une fuite de mémoire de l'ordre de 2 Go. Dès que j'ai ajouté la fermeture, le geyser est devenu un filet.
Richard

9
@Richard: Lisez attentivement l'intégralité du fil de discussion. L'auteur de Go gcet l'auteur de ces gccgochaînes closene sont pas nécessaires, sauf si vous recherchez un fichier close. Ce sont des conseils faisant autorité.
peterSO

6
@peterSO, c'est peut-être, mais je sais ce que j'ai vu et c'est ce que j'ai rapporté, alors ne me renvoyez pas.
Richard

1
Eh bien, si vous avez un canal tamponné, l'ajout de messages devrait utiliser de la mémoire. Cependant, si votre canal n'est pas mis en mémoire tampon ou si rien n'est ajouté, l'utilisation de la mémoire n'augmentera pas.
metakeule


31

Oui, vous pouvez garder une chaîne ouverte. Comme l' indique le livre du langage de programmation go :

Vous n'avez pas besoin de fermer toutes les chaînes lorsque vous en avez terminé. Il n'est nécessaire de fermer un canal que lorsqu'il est important de dire aux goroutines de réception que toutes les données ont été envoyées. Un canal que le garbage collector détermine comme inaccessible verra ses ressources récupérées, qu'il soit fermé ou non. (Ne confondez pas cela avec l'opération de fermeture pour les fichiers ouverts. Il est important d'appeler la méthode Close sur chaque fichier lorsque vous avez terminé.)


7

Oui, il est normal de laisser la chaîne ouverte, et en fait c'est typique. Un canal ouvert ne constitue pas une référence à l'objet canal et ne l'empêche donc pas d'être ramassé.


1

" Un principe général d'utilisation des canaux Go est de ne pas fermer un canal du côté du récepteur et de ne pas fermer un canal si le canal a plusieurs expéditeurs simultanés. "

Comme clairement mentionné dans la réponse ci-dessus, chaque canal sera finalement GCed une fois qu'il sera marqué pour le nettoyage, il est donc normal de laisser le canal non fermé, la seule différence que cela fera est que ce canal sera disponible gcaprès quelques cycles, peut-être si pas fermé explicitement.

Également les articles suivants ceci et cela montrent différentes façons de fermer un canal dans le cas de 1: N, N: 1 ou M: N (expéditeurs: récepteurs)


-5

Go est ramassé, vous n'avez donc pas vraiment besoin de «libérer» quoi que ce soit.

Il est possible de fermer les canaux, mais il est principalement utilisé pour - fermer (canal) - dire au goroutine (ou au programme principal) que rien d'autre ne sera envoyé sur ce canal.


8
AFAIK même dans un langage garbage collector, un programmeur est toujours responsable de la libération des ressources non gérées, par exemple la fermeture des fichiers, des sockets, etc. Dois-je fermer le canal comme un fichier?
Kluyg

3
@Kluyg La réponse est non. Vous parlez des ressources du système d'exploitation (quels canaux ne le sont pas). Cela dépend d'une ressource et d'une langue, mais il est généralement recommandé de fermer manuellement les ressources du système d'exploitation non pas parce que GC ne le ferait pas, mais plutôt parce que ce n'est pas déterministe. Le gotcha associé le plus courant est une erreur de trop grand nombre de fichiers ouverts . Vous continuez à ouvrir des fichiers ... Vous vous attendez à ce que GC le fasse ... Vous ne manquez pas de mémoire (donc GC ne démarre pas) ... Vous manquez de descripteurs de fichiers au niveau du système d'exploitation. OS tue le processus :)
Pijusn

Je ne comprends pas pourquoi cela a reçu autant de votes négatifs alors que c'était correct tout le temps et que les autres réponses acceptées
étaient identiques
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.