Maison  >  Article  >  développement back-end  >  La portée du canal tampon dans Go bloque

La portée du canal tampon dans Go bloque

WBOY
WBOYavant
2024-02-09 09:42:30659parcourir

Go 中缓冲通道的范围是阻塞的

éditeur php Yuzai Dans le langage Go, le canal buffer est un outil puissant et flexible. Les canaux tamponnés fournissent un mécanisme de synchronisation entre l'envoi et la réception de données, permettant de contrôler la vitesse et l'ordre de communication. Sa portée est bloquante, ce qui signifie que lorsque le canal est plein ou vide, les opérations d'envoi et de réception seront bloquées jusqu'à ce que suffisamment d'espace ou de données soient disponibles. Ce mécanisme peut efficacement éviter la concurrence entre les ressources et les problèmes de blocage dans les programmes concurrents, et améliorer la fiabilité et les performances du programme. En utilisant rationnellement les canaux tampons, les développeurs peuvent mieux contrôler le processus d'exécution des programmes simultanés et améliorer l'efficacité et la stabilité des programmes.

Contenu de la question

Il doit y avoir quelque chose qui ne va pas avec mon cerveau, mais j'ai été bloqué lors de l'itération du canal tampon

    results := []search.book{}
    resultsstream := make(chan []search.book, 2)
    defer close(resultsstream)

    // parallelize searches to optimize response time
    for _, src := range sources {
        go src.search(bookname, resultsstream)
    }

    counter := 0
    for sourceresults := range resultsstream {
        counter = counter + 1
        results = append(results, sourceresults...)

        fmt.println(counter)
    }

    fmt.println("never called")

Sortie

1
2

Cela prouve que 2 sources remplissent le canal (ce qui est la capacité maximale). Qu'est-ce que j'oublie ici? never called n'est, eh bien, jamais appelé.

Modifier

    var wg sync.WaitGroup
    results := []search.Book{}
    resultsStream := make(chan []search.Book, len(sources))
    defer close(resultsStream)

    // parallelize searches to optimize response time
    for _, src := range sources {
        wg.Add(1)
        go src.Search(bookName, resultsStream, &wg)
    }

    wg.Wait()
    close(resultsStream)
    for sourceResults := range resultsStream {
        results = append(results, sourceResults...)
    }

    c.JSON(http.StatusOK, gin.H{
        "results": results,
    })

Workaround

Loop for sourceResults := range resultsStream Recevez à plusieurs reprises les valeurs du canal jusqu'à sa fermeture. La boucle se termine une fois que l'expéditeur a terminé et fermé le canal.

Vous pouvez créer un nouveau canal pour chaque recherche parallèle et une fois que toutes les coroutines de travail sont terminées, vous pouvez fermer le canal. Cela mettra fin à la boucle du récepteur (remarque : ne fermez pas le canal du côté du récepteur car l'expéditeur ne le saura pas et l'envoi vers un canal fermé provoquera une panique).

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer