Maison > développement back-end > Golang > le corps du texte

Il y a un problème avec le canal Go, envoi sur un canal fermé

WBOY
Libérer: 2024-02-11 18:21:08
avant
1199 Les gens l'ont consulté

go 通道出现问题,在封闭通道上发送

L'éditeur php Youzi peut rencontrer certains problèmes lors du processus de développement en utilisant le langage Go. L'un d'eux est le problème lors de l'envoi de données sur un canal fermé. Ce problème peut provoquer un blocage des chaînes et une stagnation du programme, affectant le fonctionnement de l'ensemble de l'application. Avant de résoudre ce problème, nous devons d’abord comprendre ce qu’est un canal fermé et pourquoi l’envoi de données sur un canal fermé est problématique. Ensuite, nous approfondirons ce problème et proposerons des solutions pour réparer et optimiser nos applications Go.

Contenu de la question

J'obtiens une erreur fatale : "Envoi sur un canal fermé" et parfois j'exécute ce code, j'ai essayé plusieurs solutions mais aucune n'a fonctionné, voici la représentation du code, facile à comprendre et à utiliser test d'usage :

CB14CE50B218D8EAB916B15CD95527D5

Ce que je veux, c'est démarrer la fonction de requête n fois et obtenir la première requête terminée, puis fermer le canal et ne plus envoyer de requêtes au canal, si aucune des requêtes ne se termine avec succès, attendez que toutes les goroutines se terminent.

Je suppose que cela se produit parce que deux goroutines ou plus vérifient si le canal est fermé en même temps, et toutes deux essaient d'écrire dans le canal, ce qui entraîne une erreur fatale.

Erreur :

goroutine 19 [running]:
main.request(0xc00000a028, 0xc00000a030, 0x0?)
        C:/test/main.go:49 +0x135
created by main.main
        C:/test/main.go:17 +0xd3
panic: send on closed channel
Copier après la connexion

Quelqu'un peut-il expliquer pourquoi cela se produit ?

Merci d'avance

Solution de contournement

Le problème vient de la goroutine de réception (main) 过早关闭 outputCh. Une autre goroutine peut toujours essayer d'envoyer dessus.

Voici une autre façon :

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    output := make(chan string)
    stop := make(chan bool)
    done := make(chan bool)

    for i := 0; i < 20; i++ {
        wg.Add(1)
        go request(output, stop, &wg)
    }

    go func() {
        wg.Wait()
        done <- true
    }()

    firstOutput := <-output
    fmt.Println("output:", firstOutput)

    fmt.Println("closing the stop channel")
    close(stop)

    <-done
    fmt.Println("end of main")
}

func request(output chan string, stop chan bool, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Println("request started")
    time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)

    select {
    case output <- "test":
        fmt.Println("output sent")
    case <-stop:
        fmt.Println("stop channel is closed")
    }
}
Copier après la connexion

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!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!