Maison  >  Article  >  développement back-end  >  Problèmes lors de l'utilisation de canaux pour transmettre des données d'une goroutine à une autre

Problèmes lors de l'utilisation de canaux pour transmettre des données d'une goroutine à une autre

PHPz
PHPzavant
2024-02-08 23:21:08570parcourir

使用通道将数据从一个 goroutine 传递到另一个 goroutine 时出现的问题

Dans la programmation simultanée en langage Go, l'utilisation de canaux est un moyen courant de transférer des données entre différentes goroutines. Cependant, certains problèmes peuvent survenir lors du transfert de données d'une goroutine à une autre. L'éditeur PHP Apple présentera ces problèmes et proposera des solutions dans cet article pour vous aider à mieux comprendre et gérer les difficultés que vous pouvez rencontrer lors de l'utilisation de canaux en programmation simultanée.

Contenu de la question

J'ai pu développer le code suivant, qui est censé transmettre des données d'une routine à une autre en utilisant les canaux go :

package main

import (
    "fmt"
    "sync"
)

func generateNumbers(total int, wg *sync.WaitGroup) {
    defer wg.Done()
    ch :=make(chan int)

    sum :=0
    for idx := 1; idx <= total; idx++ {
        fmt.Printf("Generating number %d\n", idx)
        sum =sum+idx
        ch <- sum
    }
}

func printNumbers(wg *sync.WaitGroup, ch chan  int) {
    defer wg.Done()

    fmt.Printf("Sum is now",ch)
    for idx := 1; idx <= 3; idx++ {
        fmt.Printf("Printing number %d\n", idx)
    }
}

func main() {
    var wg sync.WaitGroup

    ch1 :=make(chan int)

    wg.Add(2)
    go printNumbers(&wg,ch1)
    go generateNumbers(3, &wg)

    fmt.Println("Waiting for goroutines to finish...")
    wg.Wait()
    fmt.Println("Done!")
}

J'essaie de transmettre des données (valeur de Sum ) de generateNumbers à la routine printNumbers.

Mais j'ai rencontré le problème suivant :

Waiting for goroutines to finish...
Generating number 1
Sum is now%!(EXTRA chan int=0xc000102060)Printing number 1
Printing number 2
Printing number 3
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc000118270?)
    /usr/local/go/src/runtime/sema.go:62 +0x27
sync.(*WaitGroup).Wait(0x4ba3a8?)
    /usr/local/go/src/sync/waitgroup.go:116 +0x4b
main.main()
    /tmp/tgPhZuPV77.go:42 +0x12f

goroutine 19 [chan send]:
main.generateNumbers(0x3, 0x0?)
    /tmp/tgPhZuPV77.go:19 +0xf2
created by main.main
    /tmp/tgPhZuPV77.go:39 +0xe5
exit status 2

S'il vous plaît, aidez-moi, je suis nouveau sur Golang.

Solution

Il y a quelques erreurs dans le programme ci-dessus.

  1. Les deux fonctions printNumbers et generateNumbers doivent utiliser la même variable chan.
  2. Vous devriez lire les données de la variable chan de ch.
  3. La fonction generateNumbers ne doit pas déclarer et créer des variables chan à plusieurs reprises.

J'ai modifié le code ci-dessus comme suit :

func generateNumbers(total int, wg *sync.WaitGroup, ch chan int) {
    defer wg.Done()

    sum := 0
    for idx := 1; idx <= total; idx++ {
        fmt.Printf("Generating number %d\n", idx)
        sum = sum + idx
        ch <- sum
    }
}

func printNumbers(wg *sync.WaitGroup, ch chan int) {
    defer wg.Done()

    fmt.Printf("Sum is now:\n")
    for idx := 1; idx <= 3; idx++ {
        sum := <-ch
        fmt.Printf("Printing number %d %d\n", idx, sum)
    }
}

func main() {
    var wg sync.WaitGroup

    ch1 := make(chan int)

    wg.Add(2)
    go printNumbers(&wg, ch1)
    go generateNumbers(3, &wg, ch1)

    fmt.Println("Waiting for goroutines to finish...")
    wg.Wait()
    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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer