0{"/> 0{">

Maison  >  Article  >  développement back-end  >  Erreur fatale : tous les goroutines dorment - impasse ! Erreur d'exécution

Erreur fatale : tous les goroutines dorment - impasse ! Erreur d'exécution

王林
王林avant
2024-02-10 16:42:19999parcourir

致命错误:所有 goroutine 都在睡觉 - 死锁!错误执行

l'éditeur php Strawberry vous présentera une erreur de programmation courante dans cet article : erreur fatale : "Toutes les goroutines dorment - blocage ! Erreur d'exécution". C'est l'une des erreurs courantes du langage Go et l'un des défis que les développeurs rencontrent souvent. Dans cet article, nous expliquerons en détail la cause et la solution de cette erreur pour aider chacun à mieux comprendre et gérer ce problème. Que vous soyez débutant ou développeur expérimenté, vous obtiendrez de précieuses informations et conseils grâce à cet article. Explorons ensemble !

Contenu de la question

Je suis très nouveau dans la concurrence en go, j'ai donc essayé un exemple avec des canaux et des goroutines. Je veux le modèle producteur-consommateur. La fonction producteur donne toujours des chaînes aléatoires et le consommateur les modifie en les mettant en majuscules. Je souhaite l'exécuter pendant une durée limitée (2 secondes).

package main

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

func producer(x []string, c chan string) {
    i := 1
    for i > 0 {
        randomIndex := rand.Intn(len(x))
        pick := x[randomIndex]
        c <- pick
    }
}

func consumer(x string, c chan string) {
    x1 := strings.ToUpper(x)
    c <- x1
}

func main() {

    s := []string{"one", "two", "three", "four"}
    c1 := make(chan string)
    d1 := make(chan string)
    go producer(s, c1)
    go consumer(<-c1, d1)

    stop := time.After(2000 * time.Millisecond)
    for {
        select {
        case <-stop:
            fmt.Println("STOP AFTER 2 SEC!")
            return
        default:
            fmt.Println(<-d1)
            time.Sleep(50 * time.Millisecond)
        }
    }
}

Je ne reçois qu'un seul élément du tableau et quelques erreurs. Quels changements doivent être apportés pour que cet exemple fonctionne ?

Sortie :

Deux

ERREUR FATALE : tous les goroutines dorment - impasse !

goroutine 1 [chan recevoir] : main.main()

Coroutine 6 [chan send] : main.producter({0xc00004e040, 0x4, 0x0?}, 0x0?) Créé par principal. principal Statut de sortie 2

Solution de contournement

Votre consommateur doit fonctionner en boucle, cela a déjà été mentionné.

Modifiez le premier paramètre de consumer pour qu'il soit chan字符串 au lieu d'une chaîne. De cette façon, le producteur peut continuer à écrire sur cette chaîne pour que le consommateur puisse publier sur une autre chaîne jusqu'à l'expiration du délai.

func consumer(consumechan chan string, outch chan string) {
    for {
        select {
        case s := <- consumechan:
            s = strings.toupper(s)
            outch <- s
        }
    }
}

Maintenant, lors de l'appel de go consumer() 之前的主函数中,您正在等待生产者对 c1 通道的第一个响应。不要这样做,而是将 c1, le canal est passé comme premier argument.

func main() {
    s := []string{"one", "two", "three", "four"}
    c1 := make(chan string)
    d1 := make(chan string)
    go producer(s, c1)
    go consumer(c1, d1)

    stop := time.After(2000 * time.Millisecond)
    for {
        select {
        case <-stop:
            fmt.Println("STOP AFTER 2 SEC!")
            return
        case response := <- d1:
            fmt.Println(response)
            time.Sleep(50 * time.Millisecond)
        }
    }
}

Cela devrait montrer que le producteur écrit continuellement des nombres aléatoires sur le canal c1 et que le consommateur écrit continuellement tout le texte en majuscules sur le canal d1 jusqu'à ce que les 2 secondes soient écoulées.

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