Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Isu apabila menggunakan saluran untuk menghantar data dari satu goroutine ke yang lain

Isu apabila menggunakan saluran untuk menghantar data dari satu goroutine ke yang lain

PHPz
PHPzke hadapan
2024-02-08 23:21:08616semak imbas

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

Dalam pengaturcaraan serentak dalam bahasa Go, menggunakan saluran ialah cara biasa untuk memindahkan data antara gorouti yang berbeza. Walau bagaimanapun, beberapa masalah mungkin timbul apabila menghantar data dari satu goroutine ke yang lain. Editor PHP Apple akan memperkenalkan masalah ini dan menyediakan penyelesaian dalam artikel ini untuk membantu anda lebih memahami dan menghadapi kesukaran yang mungkin anda hadapi apabila menggunakan saluran dalam pengaturcaraan serentak.

Kandungan soalan

Saya telah dapat membangunkan kod berikut, yang sepatutnya menghantar data dari satu rutin ke rutin yang lain menggunakan saluran 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!")
}

Saya cuba menghantar data (nilai Sum ) daripada generateNumbers ke rutin printNumbers.

Tetapi saya menghadapi masalah berikut:

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

Tolong bantu, saya baru di Golang.

Penyelesaian

Terdapat beberapa ralat dalam program di atas.

  1. Dua fungsi printNumbers dan generateNumbers mesti menggunakan pembolehubah chan yang sama.
  2. Anda harus membaca data pembolehubah chan daripada ch.
  3. Fungsi generateNumbers tidak sepatutnya mengisytiharkan dan mencipta pembolehubah chan berulang kali.

Saya mengubah suai kod di atas seperti berikut:

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!")
}

Atas ialah kandungan terperinci Isu apabila menggunakan saluran untuk menghantar data dari satu goroutine ke yang lain. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam