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

PHPz
Lepaskan: 2024-02-08 23:21:08
ke hadapan
592 orang telah melayarinya

使用通道将数据从一个 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!")
}
Salin selepas log masuk

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
Salin selepas log masuk

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!")
}
Salin selepas log masuk

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!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!