Maison  >  Article  >  développement back-end  >  golang fermer chan

golang fermer chan

WBOY
WBOYoriginal
2023-05-16 14:33:08933parcourir

En langage Go, la chaîne est une notion très importante. Les canaux fournissent un moyen de transmettre des données en toute sécurité entre différents Goroutines. En utilisant des canaux, nous pouvons empêcher plusieurs Goroutines d'accéder en toute sécurité à l'espace mémoire partagé, réduisant ainsi la probabilité de conditions de concurrence dans le programme.

Nous savons que lors de l'utilisation d'un canal, l'expéditeur doit écrire des données sur le canal, puis le récepteur lit les données du canal. Cependant, une fois les données reçues dans le canal, comment s'assurer que le canal est fermé normalement ? Dans cet article, nous verrons comment fermer une chaîne et ce que vous devez prendre en compte lors de la fermeture d'une chaîne.

1. Pourquoi devez-vous fermer le canal ?

Lorsque nous utilisons un canal, nous utilisons généralement une boucle for range pour itérer les éléments du canal. Par exemple, voici un exemple de lecture de données à partir d'un canal :

func readData(ch chan int) {
    for data := range ch {
        fmt.Println(data)
    }
}

Dans le code ci-dessus, nous avons utilisé une boucle for range pour parcourir les éléments du canal. Mais que se passe-t-il si la chaîne n’a jamais de données à lire ? Dans ce cas, la boucle for range bloquera toujours l'attente de l'arrivée des données, ce qui empêchera le programme de se terminer normalement.

Par conséquent, nous avons besoin d'un moyen de fermer le canal afin que le programme puisse se terminer normalement après avoir lu toutes les données. De plus, la fermeture du canal peut également rappeler au récepteur que le canal n'a aucune donnée disponible, évitant ainsi certaines situations de blocage ou de blocage inutiles.

2. Comment fermer la chaîne

En langage Go, vous pouvez utiliser la fonction de fermeture intégrée pour fermer la chaîne. La signature de la fonction close est la suivante :

func close(ch chan<- Type)

Dans la signature ci-dessus, le symbole <- représente la direction du canal. ch chan<-Type indique que ch est un canal en écriture seule et ne peut être utilisé que pour envoyer des données. Par conséquent, la fonction close ne peut être utilisée que pour fermer un canal pouvant envoyer des données.

Ce qui suit est un exemple d'utilisation de la fonction close pour fermer un canal :

func main() {
    ch := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i
        }
        close(ch)
    }()
    for data := range ch {
        fmt.Println(data)
    }
}

Dans le code ci-dessus, nous créons d'abord un canal entier ch. Ensuite, nous utilisons un Goroutine pour envoyer en continu des données au canal. Après avoir envoyé 10 numéros, nous appelons la fonction close pour fermer le canal.

Ensuite, nous utilisons une boucle for range pour parcourir les éléments du canal et les imprimer. Une fois que toutes les données du canal ont été lues, la boucle for range se terminera automatiquement.

3. Fermez les canaux sans tampon et les canaux avec tampon

Dans l'exemple ci-dessus, nous montrons comment utiliser la fonction de fermeture pour fermer le canal sans tampon. Lors de la fermeture d'un canal sans tampon, toutes les données doivent être lues, sinon un blocage se produira. S'il y a des goroutines bloquant le canal avant qu'il ne soit fermé, ils recevront le signal de fermeture du canal et sortiront.

Lorsque nous fermons le canal tamponné, il se peut que certaines données n'aient pas été lues. Lors de la fermeture d'un canal tamponné, toutes les données du canal seront lues en premier, puis un signal de fermeture sera envoyé à toutes les Goroutines.

Nous pouvons montrer comment fermer un canal tamponné en modifiant l'exemple ci-dessus :

func main() {
    ch := make(chan int, 10)
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i
        }
        close(ch)
    }()
    for data := range ch {
        fmt.Println(data)
    }
}

Dans le code ci-dessus, nous déclarons le canal ch comme canal tamponné et définissons le longueur tamponnée à 10. Nous utilisons un Goroutine pour envoyer en continu des données au canal. La même opération que la fermeture du canal sans tampon, nous utilisons la fonction close pour fermer le canal après l'envoi de 10 numéros. Dans le Goroutine principal, nous utilisons une boucle for range pour parcourir les données du canal et les afficher.

S'il y a des Goroutines qui sont bloquées sur le canal après la fermeture du canal, ils recevront le signal de fermeture du canal et sortiront donc. De plus, s'il y a des données non lues dans le canal, ces données seront automatiquement supprimées après la fermeture du canal.

4. Fermez la chaîne en toute sécurité

Lors de la fermeture de la chaîne, nous devons faire attention à certaines choses pour assurer le fonctionnement normal du programme :

#🎜 🎜#1. Ne fermez pas le canal pendant des opérations de lecture et d'écriture simultanées

Si vous lisez et écrivez le même canal dans plusieurs Goroutines en même temps et que la fonction de fermeture est appelée dans l'une des Goroutines , cela peut entraîner l'échec d'autres Goroutines sur le canal. Une exception s'est produite dans les opérations de lecture et d'écriture.

Par conséquent, lorsque nous utilisons des canaux, nous devons éviter autant que possible de lire et d'écrire le même canal dans plusieurs Goroutines en même temps. Si nous devons lire et écrire sur le même canal en même temps, nous devons utiliser des verrous ou d'autres primitives de synchronisation pour garantir la sécurité de la concurrence.

2. Ne fermez pas la chaîne à plusieurs reprises

Si nous essayons de fermer la même chaîne plusieurs fois, une exception de panique se produira. Par conséquent, avant de fermer la chaîne, nous devons nous assurer que la chaîne n’a pas encore été fermée.

Un canal donné peut être vérifié en utilisant la valeur ok-idit :

v, ok := <- ch
if ok {
    // ch 未关闭,执行读取操作
} else {
    // ch 已关闭,执行相应的操作
}

Si le canal a été fermé, la valeur ok sera fausse. Nous pouvons utiliser cette méthode pour vérifier si le canal est fermé avant de le lire.

3. Ne fermez pas le canal dans le Goroutine qui reçoit le canal

Normalement, nous devrions utiliser la fonction de fermeture dans le Goroutine qui envoie des données pour fermer le canal. La fermeture du canal dans le Goroutine qui reçoit les données peut entraîner les problèmes ci-dessus, tels que des opérations de lecture et d'écriture anormales sur le canal par d'autres Goroutines.

Par conséquent, lors de l'utilisation des chaînes, nous devons nous assurer que les chaînes sont utilisées correctement pour éviter des problèmes similaires.

5. Résumé

Dans cet article, nous avons expliqué comment fermer une chaîne et ce que vous devez prendre en compte lors de la fermeture d'une chaîne. Les canaux sont une primitive de concurrence très importante dans le langage Go. La bonne façon d'utiliser les canaux peut efficacement éviter des problèmes tels que des conditions de concurrence et des blocages dans le programme.

Par conséquent, lors de l'écriture de code, nous devons pleinement comprendre les principes et l'utilisation des canaux, et utiliser les canaux de manière raisonnable pour réaliser des opérations simultanées. Lors de la fermeture de la chaîne, nous devons prêter attention aux problèmes tels que les opérations simultanées de la chaîne dans plusieurs Goroutines et la fermeture répétée de la chaîne pour garantir le bon fonctionnement du programme.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn