Горутины

Горутина — это функция, выполняющаяся конкурентно с другими горутинами в том же адресном пространстве. Горутины гораздо легче потоков ОС: начальный стек занимает всего несколько килобайт, а планировщик Go распределяет тысячи горутин по небольшому числу системных потоков.

Запуск горутины

Достаточно поставить ключевое слово go перед вызовом функции:

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 3; i++ {
        fmt.Println(s, i)
        time.Sleep(100 * time.Millisecond)
    }
}

func main() {
    go say("горутина")
    say("main")
}

Когда функция main завершается, программа заканчивает работу, не дожидаясь остальных горутин. Поэтому для ожидания используют каналы или sync.WaitGroup, а не time.Sleep.

Анонимные функции

for i := 0; i < 3; i++ {
    go func(n int) {
        fmt.Println("работник", n)
    }(i)
}

Начиная с Go 1.22 переменная цикла создаётся заново на каждой итерации, поэтому замыкание go func() { fmt.Println(i) }() тоже работает корректно.

Модель G-M-P

Советы