Home > Backend Development > Golang > How Can I Prioritize Channels in Go's `select` Statement?

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

Patricia Arquette
Release: 2024-12-03 03:18:13
Original
366 people have browsed it

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

Priority in Go Select Statement

When working with multiple channels using Go's select statement, the order in which channels are handled is not guaranteed. To prioritize one channel over another, a workaround is available.

Problem Statement

In the code snippet below, the goal is to ensure that all values in the out channel are processed before the exit channel:

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")
}
Copy after login

However, using the select statement doesn't provide priority for one channel over the other.

Solution: Native Language Support

Go natively supports prioritizing channels in a select statement by restricting the visibility of the "quit" channel to only the producer. When the producer decides to quit, it closes the channel. The consumer will only quit when the channel is empty and closed.

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)
}
Copy after login

In this example, the quit channel is only visible to the producer function (produceEndlessly). The producer randomly decides to quit after a certain delay. The consumer function (main) iterates over the vals channel until it is closed and empty. By prioritizing the producer's "quit" message, all values in the vals channel are processed before the program exits.

The above is the detailed content of How Can I Prioritize Channels in Go's `select` Statement?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template