Порядок и main-обрыв
Первая беда прилетела сразу: ночная утилита завершалась раньше фоновых загрузок, и часть файлов оставалась необработанной. Баг заметили только утром, когда отчёт за ночь оказался пустым.
порядок исполнения горутин не гарантирован, а выход из main завершает процесс, не дожидаясь остальных горутин.
Порядок не гарантирован
Что здесь показано
- Стек — локальные переменные функции.
i = 3— значение;p = ptr → 10— указатель на значение;b = "hello"— срез (заголовок: указатель + длина + ёмкость). - Куча — данные, на которые ссылаются переменные:
rodata— байты строки-литерала (в бинарнике),данные N Б— бэкинг-массив слайса,строка— динамическая строка. - Горутины — лёгкие потоки Go: статус (running/runnable/waiting…), функция, в которой каждая сейчас находится, размер стека (растёт по мере работы) и пометка «из main» — горутина запущена из твоего кода.
- GC — сборщик мусора: фаза (off/mark) и число завершённых циклов.
Горутины исполняются независимо, и в каком порядке они доберутся до своего кода — решает планировщик. Две горутины, запущенные подряд, могут выполниться в любом порядке, а их операции — перемешаться.
Нет неявного ожидания
Между горутинами нет отношения «одна подождала другую», пока ты сам его не выстроишь. Про способы синхронизации — каналы, WaitGroup, мьютексы — следующие модули.
Main — обрыв, а не ожидание
func main() {
go func() {
time.Sleep(time.Second)
fmt.Println("не успею")
}()
// main возвращается — процесс завершается, горутина умирает
}
Строка «не успею» не напечатается. Это легко пропустить в коде, где горутины запускаются и про них забывают: на вид всё работает, а на деле часть работы отбрасывается на выходе. Утилита Миши именно так потеряла ночные загрузки. Дожидаться нужно явно — sync.WaitGroup.
Вы узнаете:
- почему «не успею» может иногда напечататься
- как
sync.WaitGroup.Waitсравнивается с обычным ожиданием
Проверьте себя
Гарантирован ли порядок вывода двух горутин, запущенных подряд?
В main запущена фоновая горутина со sleep 50 мс, и main сразу возвращается. Что произойдёт?
Две горутины печатают в цикле 1 и 2. Какой вывод возможен?
правильных ответов
Порядок горутин не определён; между ними нет неявного ожидания; выход из main обрывает всех. Синхронизация — всегда явная.
10 000 ₽ · 60 минут · онлайн