Что такое горутины?
Горутина — это лёгкий поток, управляемый средой выполнения Go. Можно запускать тысячи горутин одновременно — они намного дешевле системных потоков ОС.
package main
import (
"fmt"
"time"
)
func sayHello(name string) {
fmt.Println("Привет,", name)
}
func main() {
go sayHello("Alice") // запускается конкурентно
go sayHello("Bob")
time.Sleep(100 * time.Millisecond) // ждём завершения горутин
}
Каналы
Каналы — трубы, соединяющие горутины. Можно отправить значение в канал из одной горутины и получить его в другой:
ch := make(chan int)
go func() {
ch <- 42 // отправить значение
}()
value := <-ch // получить значение
fmt.Println(value) // 42
Буферизованные каналы
ch := make(chan string, 3) // размер буфера 3
ch <- "первый"
ch <- "второй"
ch <- "третий"
fmt.Println(<-ch) // первый
fmt.Println(<-ch) // второй
Оператор select
ch1 := make(chan string)
ch2 := make(chan string)
go func() { ch1 <- "один" }()
go func() { ch2 <- "два" }()
select {
case msg1 := <-ch1:
fmt.Println("Получено из ch1:", msg1)
case msg2 := <-ch2:
fmt.Println("Получено из ch2:", msg2)
}
WaitGroup — ожидание горутин
import "sync"
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Println("Воркер", id, "завершён")
}(i)
}
wg.Wait() // блокируется до завершения всех горутин
fmt.Println("Все воркеры завершены")