277 votes

Est-il possible de laisser un canal ouvert ?

Est-il possible de laisser un canal Go ouvert pour toujours (sans jamais le fermer) si je ne vérifie jamais son état ? Cela va-t-il conduire à des fuites de mémoire ? Le code suivant est-il acceptable ?

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

425voto

peterSO Points 25725

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

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

Question de conception : Fermeture du canal

11 votes

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

16 votes

@Richard : Lisez attentivement l'ensemble du fil de discussion. L'auteur de Go gc et l'auteur de gccgo dire le canal close ne sont pas nécessaires, à moins que vous ne cherchiez une close . C'est un conseil qui fait autorité.

9 votes

@peterSO, c'est possible, mais je sais ce que j'ai vu et c'est ce que j'ai rapporté, alors ne m'écartez pas.

71voto

JackWu Points 330

Oui, c'est bien de garder un canal ouvert. Comme le langage de programmation go livre déclaré :

Il n'est pas nécessaire de fermer chaque canal lorsque vous en avez terminé. Il est Il est seulement nécessaire de fermer un canal quand il est important de dire aux goroutines de réception que toutes les données ont été envoyées. Un canal que le que le ramasseur d'ordures considère comme inaccessible verra ses ressources ressources seront récupérées, qu'il soit fermé ou non. (Ne confondez pas ceci avec l'opération de fermeture des fichiers ouverts. Il est important d'appeler la fonction Fermer sur chaque fichier lorsque vous en avez terminé avec lui).

12voto

" Un principe général de l'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 il a été clairement mentionné dans la réponse ci-dessus que chaque canal sera finalement GCed une fois qu'il est marqué pour le nettoyage, donc il est correct de laisser le canal non fermé la seule différence que cela fera est que ce canal sera disponible pour gc après quelques cycles peut-être si elle n'est pas fermée explicitement.

Egalement les articles suivants este y este montre les différentes manières de fermer un canal dans le cas de 1:N, N:1 ou M:N (émetteurs:récepteurs).

12voto

user11809641 Points 406

Ce sujet est très bien couvert ci-dessus, mais je trouve le texte suivant de Une visite de Go très claire, qui donne également un exemple de quand il faut close :

Une autre note : Les canaux ne sont pas comme les fichiers, vous n'avez généralement pas besoin de les fermer. La fermeture n'est nécessaire que lorsque le récepteur doit être informé qu'il n'y a plus de valeurs à venir, par exemple pour mettre fin à un canal de type range boucle.

10voto

Sonia Points 6077

Oui, il n'y a pas de problème à laisser le canal ouvert, et en fait c'est typique. Un canal ouvert ne constitue pas une référence à l'objet canal, et donc ne l'empêche pas d'être ramassé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X