Go keyword Select

Keywords: Go Linux

select

Select is a key word commonly used in Go language. Linux has introduced this function to implement a non-blocking way. A select statement is used to select which case of sending or receiving operations can be executed immediately. It is similar to the switch statement, but its case involves channel-related I/O operations.

select{
case <-chan1:
    // If the data in chan1 is read successfully, the case processing statement is executed
case chan2 <- value:
    // If data is successfully written like chan2, the case processing statement is executed
default:
    // If none of the above succeeds, enter the default processing statement
}

Simple cases:

func main(){
    ch := make(chan int)
    go func(){
        ch <- 10
    }()
    time.Sleep(time.Second)
    
    select{
    case <- ch:
        fmt.Println("come to read channel")
    default:
        fmt.Println("come to default")
    }
}

Timeout control

If all case s are unsuccessful and no default statement exists, the select statement will always block until at least one I/O operation is performed, but if not, it will always block, then we can set up a timeout control.

Realization method 1, using the protocol:

func main(){
    timeout := make(chan bool)
    ch := make(chan string)
    
    go func(ch chan bool){
        time.Sleep(time.Second * 2)
        ch <- true
    }(timeout)
    
    select {
    case value := <-ch:
        fmt.Printf("value is %v",value)
    case <= timeout: 
        fmt.Println("runing timeout...")
    }
    fmt.Println("end this demo")
}

Output results:

runing timeout...
end this demo

Implementation method 2, using time.After() method to achieve:

func main(){
    ch := make(chan string)
    
    select {
    case value := <-ch:
        fmt.Printf("value is %v",value)
    case <= time.After(time.Second): 
        fmt.Println("runing timeout...")
    }
    fmt.Println("end this demo")
}

Output results:

runing timeout...
end this demo

break keyword ends select

Case study:

func main(){
    ch1 := make(chan int,1)
    ch2 := make(chan int,1)
    
    select{
    case ch1 <- 10:
        fmt.Println("this is ch1")
        break
        fmt.Println("ch1 write value")
    case ch2 <-20:
        fmt.Println("this is ch2")
        fmt.Println("ch2 write value")
    }
}

In the above code, both channels ch1 and ch2 can write values, so the system will randomly select a case to execute. When choosing to execute the case of ch1 first, because of the existence of the break keyword, only one sentence will be printed:

this is ch1

But when you execute ch2's case, everything is printed:

this is ch2
ch2 write value

Posted by golfinggod on Sat, 05 Oct 2019 22:53:52 -0700