Ответ
В Go этот подход основан на горутинах (goroutines) и каналах (channels), что соответствует философии "Do not communicate by sharing memory; instead, share memory by communicating" (Не общайтесь, разделяя память; вместо этого разделяйте память, общаясь).
Горутины (Goroutines) — это легковесные потоки, управляемые рантаймом Go, а не напрямую операционной системой. Их создание и переключение между ними гораздо дешевле, чем у системных потоков.
Каналы (Channels) — это типизированные "конвейеры", через которые горутины могут безопасно обмениваться данными, избегая состояния гонки.
Планировщик Go (Go Scheduler) — это ключевой компонент рантайма, который эффективно распределяет M горутин по N потокам операционной системы (модель M:N). Он самостоятельно решает, какая горутина будет выполняться в какой момент, обеспечивая высокую производительность и утилизацию CPU.
Пример (Пул воркеров):
// worker — горутина, которая читает задачи из канала `tasks` и отправляет результат в `results`.
func worker(id int, tasks <-chan int, results chan<- int) {
for task := range tasks {
fmt.Printf("Воркер %d обработал задачу %dn", id, task)
time.Sleep(time.Second) // Имитация работы
results <- task * 2
}
}
func main() {
taskCount := 10
workerCount := 3
tasks := make(chan int, taskCount)
results := make(chan int, taskCount)
// Запуск пула воркеров (горутин)
for i := 1; i <= workerCount; i++ {
go worker(i, tasks, results)
}
// Отправка задач в канал
for i := 1; i <= taskCount; i++ {
tasks <- i
}
close(tasks) // Важно закрыть канал, чтобы воркеры завершили работу
// Сбор результатов
for i := 1; i <= taskCount; i++ {
<-results
}
fmt.Println("Все задачи выполнены")
}