Tidak dapat menerima nilai terakhir yang dihantar sepanjang saluran dalam goroutine utama Golang

WBOY
Lepaskan: 2024-02-09 11:33:09
ke hadapan
527 orang telah melayarinya

主 goroutine Golang 中无法接收沿通道发送的最后一个值

Tidak dapat menerima nilai terakhir yang dihantar sepanjang saluran dalam goroutine utama Golang. Ini kerana apabila saluran ditutup, goroutine tidak boleh menerima nilai baru lagi. Sebaliknya, ia menyekat operasi terima sehingga semua nilai dalam saluran telah diterima. Ini adalah pilihan reka bentuk di Golang untuk mengelakkan kemungkinan situasi kebuntuan semasa operasi penerimaan. Oleh itu, kita perlu memberi perhatian khusus kepada perkara ini semasa menulis program Golang untuk mengelakkan masalah dan ralat yang berpotensi.

Kandungan soalan

Diberi pengimbas port TCP dalam golang. 2 perlaksanaan, pertama saya dan kedua dari buku golang. Anggap yang kedua adalah 100% boleh dilaksanakan, kerana ramai pembaca telah menguji sebelum ini. Tetapi nampaknya kedua-duanya mempunyai masalah yang sama: nilai terakhir yang dihantar dalam saluran hasil tidak boleh diterima dalam coroutine utama, ia tersekat menunggu tanpa terhingga nilai dari saluran, walaupun nilai sebenarnya dihantar. Beberapa pemerhatian: Apabila bilangan port kurang daripada 21, ia berfungsi seperti yang dijangkakan apabila jumlah melebihi 1000, jumlah yang tidak diterima meningkat kepada sekitar 10. Saya tidak faham mengapa.

Pelaksanaan dalam buku

func worker(ports, results chan int) {
    for p := range ports {
        address := fmt.Sprintf("scanme.nmap.org:%d", p)
        conn, err := net.Dial("tcp", address)
        if err != nil {
            results <- 0
            fmt.Println("sent", p)
            continue
        }
        conn.Close()
        results <- p
        fmt.Println("sent", p)
    }
}

func main() {
    ports := make(chan int, 100)
    results := make(chan int)

    var openports []int

    for i := 0; i < cap(ports); i++ {
        go worker(ports, results)
    }

    go func() {
        for i := 1; i <= 50; i++ {
            ports <- i
        }
    }()

    for i := 0; i < 50; i++ {
        port := <-results // after 49 it gets stuck infinitely, never proceed further
        fmt.Println("received", port, i)
        if port != 0 {
            openports = append(openports, port)
        }
    }

    close(ports)
    close(results)

    sort.Ints(openports)

    fmt.Println(openports)

}
Salin selepas log masuk

Penyelesaian

Isu ini telah diselesaikan dengan menambahkan tamat masa pada net.Dialer

func worker(ports, results chan int) {
    dialer := net.Dialer{Timeout: time.Second}

    for p := range ports {
        address := fmt.Sprintf("scanme.nmap.org:%d", p)
        conn, err := dialer.Dial("tcp", address)
        if err != nil {
            results <- 0
            continue
        }

        conn.Close()
        results <- p
    }
}
Salin selepas log masuk

Atas ialah kandungan terperinci Tidak dapat menerima nilai terakhir yang dihantar sepanjang saluran dalam goroutine utama Golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

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!