Ответ
Горутины — это легковесные потоки, управляемые средой выполнения (runtime) Go.
Создание горутины
Горутина создается с помощью ключевого слова go
, указанного перед вызовом функции. Эта функция (или метод) начинает выполняться асинхронно в новой горутине.
package main
import (
"fmt"
"time"
)
func sayHello() {
fmt.Println("Привет из горутины!")
}
func main() {
// Запускаем функцию sayHello в новой горутине
go sayHello()
fmt.Println("Привет из основной горутины (main)!")
// Даём время на выполнение другой горутины, иначе main завершится раньше
time.Sleep(100 * time.Millisecond)
}
Ключевые особенности:
- Легковесность: Начальный размер стека горутины всего ~2 КБ, в то время как у потоков ОС он значительно больше (обычно 1-8 МБ). Это позволяет создавать сотни тысяч и даже миллионы горутин одновременно.
- Управление средой выполнения: Планировщик Go (Go scheduler) эффективно распределяет горутины по реальным потокам ОС (модель M:N), обеспечивая высокий уровень параллелизма без больших накладных расходов на переключение контекста.
- Быстрый запуск: Создание и запуск горутины происходит гораздо быстрее, чем создание потока ОС.
- Коммуникация через каналы: Идиоматичный способ взаимодействия между горутинами — использование каналов (
chan
). Это помогает избежать состояний гонки при доступе к общим данным, следуя принципу: "Не обменивайтесь данными, разделяя память; разделяйте память, обмениваясь данными". - Общее адресное пространство: Все горутины выполняются в одном адресном пространстве, поэтому при доступе к общим данным без каналов необходимо использовать примитивы синхронизации (например, мьютексы из пакета
sync
).