What can select do in GoLang

  sonic0002        2023-08-12 20:17:02       1,489        0    

In Go language, select is a keyword used to listen to and perform IO operations related to channels.

With the select statement, we can simultaneously listen to multiple channels and perform corresponding operations when any of the channels are ready.

This article will summarize the common uses of the select statement and provide some considerations when using it.

Basic syntax

The basic syntax of the select statement is as follows:

select {
case <-channel1:
    // when channel1 has data to process
case data := <-channel2:
    // when channel2 has data to process
default:
    // if no channel has data ready
}

When seeing this syntax, it's easy to think of the switch statement.

Although the select statement and the switch statement may appear similar on the surface, their purposes and functionalities are different.

switch is used for conditional branching, while select is used for channel operations. You cannot use arbitrary types of conditional expressions in a select statement; it can only operate on channels.

Usages

Although the syntax is simple, there are still some points to be aware of when using it. Below are some points summarized:

  1. The select statement can only be used for channel operations, to choose between multiple channels and listen for their readiness, rather than for other types of conditional branching.

  2. The select statement can contain multiple case clauses, where each case corresponds to a channel operation. When any of the channels are ready, the corresponding case clause will be executed.

  3. If multiple channels are ready, the select statement will randomly choose one of the ready channels to execute. This ensures fair competition between multiple channels.

  4. The execution of the select statement can be either blocking or non-blocking. If none of the channels are ready and there is no default clause, the select statement will block until at least one channel becomes ready. If there is a default clause and none of the channels are ready, the select statement will execute the default clause, avoiding blocking.

Multiplexing

One of the most common uses of the select statement is to simultaneously listen to multiple channels and perform different operations based on their readiness status.

package main

import (
    "fmt"
    "time"
)

func main() {
    c1 := make(chan string)
    c2 := make(chan string)

    go func() {
        time.Sleep(3 * time.Second)
        c1 <- "one"
    }()

    go func() {
        time.Sleep(3 * time.Second)
        c2 <- "two"
    }()

    select {
    case msg := <-c1:
        fmt.Println(msg)
    case msg := <-c2:
        fmt.Println(msg)
    }
}

 When executing the above code, the program will randomly print "one" or "two". If the channel is empty, the program will block indefinitely.

Non-blocking communication

In regular read and write operations, they will block when there is no data to read or no buffer space to write.

However, with the select statement, we can execute default logic when no data is ready, avoiding the program getting stuck in an infinite waiting state.

package main

import (
    "fmt"
)

func main() {
    channel := make(chan int)

    select {
    case data := <-channel:
        fmt.Println("Received:", data)
    default:
        fmt.Println("No data available.")
    }
}

Above code will output the message in default branch:

No data available.

Timeout handling

By combining select and time.After function, we can wait for a channel to become ready within a specified time and execute the corresponding logic if the time limit is exceeded.

package main

import (
    "fmt"
    "time"
)

func main() {
    channel := make(chan int)

    select {
    case data := <-channel:
        fmt.Println("Received:", data)
    case <-time.After(3 * time.Second):
        fmt.Println("Timeout occurred.")
    }
}

When executing the above code, if there is no data to read from the channel within 3 seconds, the select statement will execute the time.After branch.

Output would be

Timeout occurred.

Summary

The select statement in Go is used for channel operations, allowing simultaneous monitoring of multiple channels and executing corresponding actions when any of the channels are ready. It provides fair competition between channels, supports blocking and non-blocking behavior, and can be combined with timeouts using the time.After function. Overall, select is a powerful tool for efficient communication and synchronization in concurrent Go programs.

TUTORIAL  SELECT  USAGE  SYNTAX  GOLANG 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

Your plan vs Reality