channel-select-go
path: courses/go-course/channel-select-go.md
- **fileName**: channel-select-go
- **Created on**: 2024-09-06 13:11:10
Channels
Channels in Go are used to communicate between goroutines. They provide a way to send and receive values between different parts of a program, helping synchronize concurrent operations.
Example:
package main
import (
"fmt"
"time"
)
func main() {
// Create a new channel of type int
messages := make(chan int)
// Launch a goroutine to send values into the channel
go func() {
for i := 0; i < 5; i++ {
messages <- i // Send value into the channel
time.Sleep(time.Second)
}
close(messages) // Close the channel when done sending
}()
// Receive values from the channel
for msg := range messages {
fmt.Println(msg) // Print received value
}
}
Explanation:
We create a channel messages of type int using make(chan int).
We launch a goroutine that sends integers (0 through 4) into the channel and then closes it.
In the main goroutine, we receive from the channel in a for loop until the channel is closed (using range).
Goroutines
Goroutines are lightweight threads managed by the Go runtime. They allow you to run functions concurrently with other functions.
Example:
package main
import (
"fmt"
"time"
)
func printNumbers() {
for i := 1; i <= 5; i++ {
fmt.Println(i)
time.Sleep(time.Second)
}
}
func printLetters() {
for _, letter := range []rune{'A', 'B', 'C', 'D', 'E'} {
fmt.Println(string(letter))
time.Sleep(500 * time.Millisecond)
}
}
func main() {
go printNumbers() // Start printNumbers as a goroutine
go printLetters() // Start printLetters as a goroutine
// Wait for goroutines to finish
time.Sleep(6 * time.Second)
}
Explanation:
printNumbers and printLetters functions are run concurrently in separate goroutines.
time.Sleep in the main function is used to keep the program running long enough for both goroutines to finish executing. In a real application, you would use more sophisticated synchronization methods, like sync.WaitGroup.
Select Statement
The select statement is used to wait on multiple channel operations. It allows a goroutine to wait on multiple communication operations, proceeding with the first one that is ready.
Example:
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(2 * time.Second)
ch1 <- "message from ch1"
}()
go func() {
time.Sleep(1 * time.Second)
ch2 <- "message from ch2"
}()
select {
case msg1 := <-ch1:
fmt.Println("Received", msg1)
case msg2 := <-ch2:
fmt.Println("Received", msg2)
case <-time.After(3 * time.Second):
fmt.Println("Timeout")
}
}
Explanation:
Two channels ch1 and ch2 are created and each is filled by separate goroutines.
The select statement listens on both channels and also includes a timeout case using time.After.
The select will choose the first case that can proceed. In this example, it will print the message from ch2 because ch2 receives a value before ch1.
continue:./struct-go.md
before:./interface-go.md