Ответ
Да, все горутины, запущенные в рамках одного процесса, разделяют одно и то же адресное пространство. Горутины — это легковесные потоки, управляемые средой выполнения Go (Go runtime), а не напрямую операционной системой. Это позволяет запускать тысячи и даже миллионы горутин одновременно.
Поскольку память общая, при одновременном доступе нескольких горутин к одним и тем же данным могут возникнуть состояния гонки (data races). Для предотвращения этого необходимы механизмы синхронизации.
В Go есть два основных подхода к безопасной работе с общей памятью:
-
Мьютексы (
sync.Mutex
): Используются для защиты критических секций кода, гарантируя, что только одна горутина в один момент времени может выполнять код, изменяющий общие данные.package main import ( "fmt" "sync" "time" ) var counter int var wg sync.WaitGroup var mu sync.Mutex func increment() { defer wg.Done() mu.Lock() // Блокируем доступ для других горутин counter++ mu.Unlock() // Освобождаем блокировку } func main() { for i := 0; i < 1000; i++ { wg.Add(1) go increment() } wg.Wait() // Ждем завершения всех горутин fmt.Println("Итоговый счетчик:", counter) // Итоговый счетчик: 1000 }
-
Каналы (channels): Реализуют идеологию Go: "Не общайтесь, разделяя память; вместо этого разделяйте память, общаясь". Данные передаются между горутинами через каналы, что исключает необходимость в явных блокировках.
Итог: Горутины разделяют память, что делает их эффективными, но требует от разработчика внимательного отношения к синхронизации доступа к данным с помощью мьютексов или каналов.