🟦 Goroutines в Go
Горутины - это лёгкие конкурентные задачи, которые позволяют выполнять
функции параллельно или асинхронно. Они создаются с помощью ключевого
слова go и работают сверхэффективно благодаря встроенному планировщику
Go.
🚀 Что такое горутина?
Горутина - это функция, запускаемая в отдельном конкурентном контексте:
go myFunc()
Особенности:
- выполнение вызывающей функции НЕ останавливается;
- горутина продолжает работать независимо;
- Go сам решает - выполнять параллельно или асинхронно;
- горутина завершается только после завершения своей функции.
📌 Пример: базовый запуск горутины
func count(amount int) {
for i := 1; i <= amount; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(i)
}
}
func main() {
go count(5)
fmt.Println("wait for goroutine")
time.Sleep(1000 * time.Millisecond)
fmt.Println("end program")
}
Ожидаемый вывод:
wait for goroutine
1
2
3
4
5
end program
Без Sleep программа завершилась бы раньше, чем горутина.
🧪 Пример: горутины + замыкания
Горутины могут запускать анонимные функции (замыкания), захватывая внешние переменные:
counter := 0
wait := func(ms time.Duration) {
time.Sleep(ms * time.Millisecond)
counter += 1
}
fmt.Println("Launching goroutines")
go wait(100)
go wait(900)
go wait(1000)
fmt.Println("Launched. Counter =", counter)
time.Sleep(1100 * time.Millisecond)
fmt.Println("Waited 1100ms. Counter =", counter)
Вывод:
Launching goroutines
Launched. Counter = 0
Waited 1100ms. Counter = 3
🔍 Важно: Все горутины делят одну и ту же переменную counter.
Это может приводить к гонкам данных, если не использовать синхронизацию.
⚠️ Важные свойства горутин
- Не блокируют вызывающую функцию
- Запускаются мгновенно
- Очень лёгкие - тысячи горутин стоят дешевле одного потока ОС
- Могут использовать замыкания
- Для общих данных требуется синхронизация (каналы, мьютексы)
🎯 Итоги
go myFunc()запускает конкурентное выполнение- Порядок выполнения недетерминирован
- Захваченные замыкания разделяются между горутинами
- Горутины - основа всей конкурентности Go