Ответ
Многопоточность (Multithreading) — это способность операционной системы или приложения выполнять несколько потоков (threads) одновременно в рамках одного процесса. Потоки разделяют общее адресное пространство (память), что упрощает обмен данными, но создает риск возникновения гонок данных (race conditions), требуя механизмов синхронизации (мьютексы, семафоры).
Реализация в Go
В Go используется иная, более высокоуровневая модель конкурентности, основанная на горутинах (goroutines) и каналах (channels).
Горутины — это легковесные потоки, управляемые не ядром ОС, а средой выполнения (runtime) Go. Они требуют гораздо меньше памяти (несколько КБ) по сравнению с системными потоками (МБ), что позволяет создавать сотни тысяч и даже миллионы горутин одновременно.
Каналы — это типизированные конвейеры, через которые можно безопасно передавать данные между горутинами. Они обеспечивают синхронизацию и предотвращают гонки данных, следуя принципу: "Не обменивайтесь данными через общую память; обменивайтесь памятью через каналы".
Пример с использованием sync.WaitGroup
для корректного ожидания:
Вместо time.Sleep()
, который является ненадежным способом ожидания, используется sync.WaitGroup
для гарантированного завершения всех горутин.
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // Уменьшаем счетчик WaitGroup при завершении функции
fmt.Printf("Worker %d startingn", id)
time.Sleep(time.Second) // Имитация работы
fmt.Printf("Worker %d donen", id)
}
func main() {
var wg sync.WaitGroup // Создаем WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1) // Увеличиваем счетчик на 1 для каждой горутины
go worker(i, &wg)
}
// Ожидаем, пока счетчик WaitGroup не станет равен 0
wg.Wait()
fmt.Println("All workers have finished")
}
Ключевые отличия от классических потоков:
- Легковесность: Горутины занимают значительно меньше ресурсов.
- Управление рантаймом: Планировщик Go эффективно распределяет горутины по системным потокам.
- Безопасная коммуникация: Каналы предоставляют встроенный механизм для синхронизации и обмена данными.