Rumah > pembangunan bahagian belakang > Golang > Bagaimanakah Saya Boleh Mengutamakan Saluran dalam Penyata `pilih` Go?

Bagaimanakah Saya Boleh Mengutamakan Saluran dalam Penyata `pilih` Go?

Patricia Arquette
Lepaskan: 2024-12-03 03:18:13
asal
367 orang telah melayarinya

How Can I Prioritize Channels in Go's `select` Statement?

Keutamaan dalam Penyata Pilih Go

Apabila bekerja dengan berbilang saluran menggunakan kenyataan pilih Go, susunan saluran dikendalikan tidak dijamin. Untuk mengutamakan satu saluran berbanding saluran lain, penyelesaian tersedia.

Pernyataan Masalah

Dalam coretan kod di bawah, matlamatnya adalah untuk memastikan semua nilai dalam saluran keluar diproses sebelum saluran keluar:

package main

import "fmt"

func sender(out chan int, exit chan bool){
    for i := 1; i <= 10; i++ {
        out <- i
    }
    exit <- true
}

func main(){
    out := make(chan int, 10)
    exit := make(chan bool)

    go sender(out, exit)

    L:
    for {
        select {
            case i := <-out:
                fmt.Printf("Value: %d\n", i)
            case <-exit:
                fmt.Println("Exiting")
                break L
        }
    }
    fmt.Println("Did we get all 10? Most likely not")
}
Salin selepas log masuk

Walau bagaimanapun, menggunakan pernyataan pilih tidak memberikan keutamaan untuk satu saluran berbanding yang lain.

Penyelesaian: Sokongan Bahasa Ibunda

Go secara asli menyokong mengutamakan saluran dalam pernyataan terpilih dengan mengehadkan keterlihatan saluran "berhenti" kepada hanya pengeluar. Apabila pengeluar memutuskan untuk berhenti, ia menutup saluran. Pengguna hanya akan berhenti apabila saluran kosong dan ditutup.

package main

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

var (
    produced  = 0
    processed = 0
)

func produceEndlessly(out chan int, quit chan bool) {
    defer close(out)
    for {
        select {
        case <-quit:
            fmt.Println("RECV QUIT")
            return
        default:
            out <- rand.Int()
            time.Sleep(time.Duration(rand.Int63n(5e6)))
            produced++
        }
    }
}

func quitRandomly(quit chan bool) {
    d := time.Duration(rand.Int63n(5e9))
    fmt.Println("SLEEP", d)
    time.Sleep(d)
    fmt.Println("SEND QUIT")
    quit <- true
}

func main() {
    vals, quit := make(chan int, 10), make(chan bool)
    go produceEndlessly(vals, quit)
    go quitRandomly(quit)
    for x := range vals {
        fmt.Println(x)
        processed++
        time.Sleep(time.Duration(rand.Int63n(5e8)))
    }
    fmt.Println("Produced:", produced)
    fmt.Println("Processed:", processed)
}
Salin selepas log masuk

Dalam contoh ini, saluran berhenti hanya boleh dilihat oleh fungsi pengeluar (produceEndlessly). Pengeluar secara rawak memutuskan untuk berhenti selepas kelewatan tertentu. Fungsi pengguna (utama) berulang melalui saluran vals sehingga ia ditutup dan kosong. Dengan mengutamakan mesej "berhenti" pengeluar, semua nilai dalam saluran vals diproses sebelum program keluar.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengutamakan Saluran dalam Penyata `pilih` Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan