Terdapat masalah dengan saluran pergi, menghantar pada saluran tertutup

WBOY
Lepaskan: 2024-02-11 18:21:08
ke hadapan
1247 orang telah melayarinya

go 通道出现问题,在封闭通道上发送

editor php Youzi mungkin menghadapi beberapa masalah semasa proses pembangunan menggunakan bahasa Go Salah satu daripadanya ialah masalah semasa menghantar data pada saluran tertutup. Masalah ini boleh menyebabkan saluran menyekat dan genangan program, menjejaskan operasi keseluruhan aplikasi. Sebelum menyelesaikan masalah ini, kita perlu memahami terlebih dahulu apakah saluran tertutup dan mengapa menghantar data pada saluran tertutup bermasalah. Seterusnya, kami akan menyelidiki isu ini dan menyediakan penyelesaian untuk membetulkan dan mengoptimumkan aplikasi Go kami.

Kandungan soalan

Saya mendapat ralat maut: "Menghantar pada saluran tertutup", kadangkala saya menjalankan kod ini, saya mencuba berbilang penyelesaian tetapi tiada satu pun yang berjaya, berikut ialah perwakilan kod, mudah difahami dan Kemudahan gunakan ujian:

CB14CE50B218D8EAB916B15CD95527D5

Apa yang saya mahukan ialah memulakan fungsi permintaan n kali dan dapatkan permintaan pertama yang lengkap, kemudian tutup saluran dan jangan hantar lebih banyak permintaan ke saluran, jika tiada satu pun permintaan berjaya diselesaikan, tunggu semua goroutine selesai.

Saya rasa ini berlaku kerana dua atau lebih goroutine menyemak sama ada saluran ditutup pada masa yang sama, dan kedua-duanya cuba menulis dalam saluran, yang mengakibatkan ralat maut.

Ralat:

goroutine 19 [running]:
main.request(0xc00000a028, 0xc00000a030, 0x0?)
        C:/test/main.go:49 +0x135
created by main.main
        C:/test/main.go:17 +0xd3
panic: send on closed channel
Salin selepas log masuk

Boleh sesiapa jelaskan mengapa ini berlaku?

Terima kasih terlebih dahulu

Penyelesaian

Masalahnya ialah dengan goroutine yang menerima (main) 过早关闭 outputCh. Beberapa goroutine lain masih boleh cuba menghantarnya.

Ini cara lain:

package main

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

func main() {
    var wg sync.WaitGroup
    output := make(chan string)
    stop := make(chan bool)
    done := make(chan bool)

    for i := 0; i < 20; i++ {
        wg.Add(1)
        go request(output, stop, &wg)
    }

    go func() {
        wg.Wait()
        done <- true
    }()

    firstOutput := <-output
    fmt.Println("output:", firstOutput)

    fmt.Println("closing the stop channel")
    close(stop)

    <-done
    fmt.Println("end of main")
}

func request(output chan string, stop chan bool, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Println("request started")
    time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)

    select {
    case output <- "test":
        fmt.Println("output sent")
    case <-stop:
        fmt.Println("stop channel is closed")
    }
}
Salin selepas log masuk

Atas ialah kandungan terperinci Terdapat masalah dengan saluran pergi, menghantar pada saluran tertutup. 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