otro ejemplo de select y case: https://tour.golang.org/concurrency/5
Case
Introducci贸n
Caracter铆sticas esenciales de Go
Qu茅 aprender谩s y qu茅 necesitas saber
Repaso general: variables, condicionales, slices y map
Repaso general: GoRoutines y apuntadores
Programaci贸n orientada a objetos
驴Es Go orientado a objetos?
Structs vs. clases
M茅todos y funciones
Constructores
Herencia
Interfaces
Aplicando interfaces con Abstract Factory
Implementaci贸n final de Abstract Factory
Funciones an贸nimas
Funciones variadicas y retornos con nombre
Go Modules
C贸mo utilizar los Go modules
Creando nuestro m贸dulo
Testing
Testing
Code coverage
Profiling
Testing usando Mocks
Implementando Mocks
Concurrencia
Unbuffered channels y buffered channels
Waitgroup
Buffered channels como sem谩foros
Definiendo channels de lectura y escritura
Worker pools
Multiplexaci贸n con Select y Case
Proyecto: servidor con worker pools
Definiendo workers, jobs y dispatchers
Creando web server para procesar jobs
Conclusi贸n
Contin煤a con el Curso de Go Avanzado
You don't have access to this class
Keep learning! Join and start boosting your career
Concurrent scheduling is essential to optimize performance and efficiency. In Go, channels are a key tool for communicating between goroutines. However, what do you do when you have multiple channels and need to manage the arrival of data non-sequentially? This is where the use of select
to implement multiplexing comes into play.
To begin with, we need to understand how channels are configured in Go. Channels allow communication and synchronization between different goroutines.
package main
import ("fmt""time")
func doSomething(duration time.Duration, channel chan int, param int) {time.Sleep(duration)channel <- param}
func main() {c1 := make(chan int)c2 := make(chan int)
duration1 := 4 * time.Secondduration2 := 2 * time.Second
go doSomething(duration1, c1, 1)go doSomething(duration2, c2, 2)
for i := 0; i < 2; i++ {select {case msg1 := <-c1:fmt.Printf("Channel 1 received: %d\n", msg1)case msg2 := <-c2:fmt.Printf("Channel 2 received: %d\n", msg2)}} }} } }
Select is a switch-like structure that allows you to listen to multiple channels at the same time, executing the case that is ready first. It allows you to handle message arrivals more flexibly than a sequential approach.
In the example above, select
is used to print the message from the channel that first sends a signal, avoiding blocking while waiting for another operation.
When concurrently handling multiple processes, the sequential approach can block the execution of faster tasks because it is waiting for a response from slower ones. Select
solves this problem by allowing more efficient, real-time handling of signals.
The use of select
is particularly useful in systems where latency is crucial or certain tasks are expected to finish at different times. This is where Go, with this operator, shows its robustness in handling concurrency without sacrificing performance.
With this knowledge, you can greatly improve your concurrent applications, making them responsive and efficient. Don't hesitate to implement select
in your future developments and you will see the difference in performance, keep exploring and learning!
Contributions 5
Questions 0
otro ejemplo de select y case: https://tour.golang.org/concurrency/5
Case
Code:
package main
import (
"fmt"
"time"
)
func doSomething(i time.Duration, c chan<- int, param int) {
time.Sleep(i)
c <- param
}
func main() {
c1 := make(chan int)
c2 := make(chan int)
d1 := 4 * time.Second
d2 := 2 * time.Second
go doSomething(d1, c1, 1)
go doSomething(d2, c2, 2)
for i := 0; i < 2; i++ {
select {
case channelMsg1 := <-c1:
fmt.Println(channelMsg1)
case channelMsg2 := <-c2:
fmt.Println(channelMsg2)
}
}
}
package main
import (
"fmt"
"time"
)
func doSomething(i time.Duration, c chan<- int, param int) {
time.Sleep(i)
c <- param
}
func main() {
c1 := make(chan int)
c2 := make(chan int)
d1 := 4 * time.Second
d2 := 2 * time.Second
go doSomething(d1, c1, 1)
go doSomething(d2, c2, 2)
/* fmt.Println("Waiting for the first result")
fmt.Println(<-c1)
fmt.Println("Waiting for the second result")
fmt.Println(<-c2) */
for i := 0; i < 2; i++ {
select {
case res := <-c1:
fmt.Println("Received", res, "from c1")
case res := <-c2:
fmt.Println("Received", res, "from c2")
}
}
}
Code
package main
import (
"fmt"
"math/rand"
"time"
)
func doSomething(i time.Duration, c chan<- int, param int) {
time.Sleep(i)
c <- param
}
func main() {
c1 := make(chan int)
c2 := make(chan int)
// generate random number
rand.Seed(time.Now().UnixNano())
d1 := time.Duration(rand.Intn(10)) * time.Second
d2 := time.Duration(rand.Intn(10)) * time.Second
go doSomething(d1, c1, 1)
go doSomething(d2, c2, 2)
/* fmt.Println("Waiting for the first result")
fmt.Println(<-c1)
fmt.Println("Waiting for the second result")
fmt.Println(<-c2) */
for i := 0; i < 2; i++ {
// wait for the completion of tasks
select {
case res := <-c1:
fmt.Println("Received", res, "from c1 after", d1)
case res := <-c2:
fmt.Println("Received", res, "from c2 after", d2)
}
}
}
En Go tambi茅n tenemos el default case como los tradicionales switch-case 馃敟
Want to see more contributions, questions and answers from the community?