Go Курс

Конкурентность в Go: горутины и каналы

Самоучитель Python 3, собранный из материалов данного сайта.Предназначен в основном для тех, кто хочет изучить язык программирования Python с нуля.

Что такое горутины?

Горутина — это лёгкий поток, управляемый средой выполнения 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("Все воркеры завершены")