Maison >développement back-end >Golang >Comment résoudre l'impasse « Tous les goroutines sont endormis » dans Go ?

Comment résoudre l'impasse « Tous les goroutines sont endormis » dans Go ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-24 16:11:10919parcourir

How to Solve the

Gérer une impasse dans les Goroutines : "Toutes les goroutines sont endormies"

Comprendre l'impasse

Dans le code fourni, vous rencontrez une impasse due au manque de gestion appropriée des canaux. Le problème se pose dans la fonction UnloadTrucks, où vous bloquez indéfiniment l'attente de l'arrivée des camions dans le canal ch. Cependant, la goroutine principale ne ferme jamais ce canal, ce qui entraîne une attente interminable.

Résoudre l'impasse

Pour résoudre l'impasse, vous devez fermer le canal ch une fois que tous les camions ont été chargés et envoyés. à travers le canal. Ceci peut être réalisé en utilisant un WaitGroup pour suivre les goroutines qui chargent les camions :

go func() {
    wg.Wait()
    close(ch)
}()

Lorsque toutes les goroutines ont terminé de charger les camions, le canal ch sera fermé, permettant à UnloadTrucks de continuer.

Code réécrit :

package main

import (
    "fmt"
    "sync"
    "time"
)

type Item struct {
    name string
}

type Truck struct {
    Cargo []Item
    name  string
}

func UnloadTrucks(c chan Truck) {

    for t := range c {
        fmt.Printf("%s has %d items in cargo: %s\n", t.name, len(t.Cargo), t.Cargo[0].name)
    }

}

func main() {
    trucks := make([]Truck, 2)

    ch := make(chan Truck)

    var wg sync.WaitGroup

    for i, _ := range trucks {

        trucks[i].name = fmt.Sprintf("Truck %d", i+1)

        fmt.Printf("Building %s\n", trucks[i].name)
    }

    for t := range trucks {
        wg.Add(1)
        go func(tr Truck) {

            itm := Item{}
            itm.name = "Groceries"

            fmt.Printf("Loading %s\n", tr.name)
            tr.Cargo = append(tr.Cargo, itm)
            ch <- tr
            wg.Done()

        }(trucks[t])
    }

    time.Sleep(50 * time.Millisecond)
    fmt.Println("Unloading Trucks")
    UnloadTrucks(ch)

    fmt.Println("Done")
}

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