@kole_will
В Go существует несколько способов распараллеливания выполнения кода:
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
func main() { go func1() go func2() // ... time.Sleep(time.Second) // Ожидание завершения всех Go рутин } func func1() { // Код функции func1 } func func2() { // Код функции func2 } |
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
func main() { ch1 := make(chan int) ch2 := make(chan int) go func1(ch1) go func2(ch2) result1 := <-ch1 // Получение данных из канала ch1 result2 := <-ch2 // Получение данных из канала ch2 // Использование результатов } func func1(ch chan int) { // Код функции func1 ch <- result1 // Помещение результата в канал ch } func func2(ch chan int) { // Код функции func2 ch <- result2 // Помещение результата в канал ch } |
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
func main() { var wg sync.WaitGroup wg.Add(2) // Устанавливаем счетчик ожидания на 2 go func1(&wg) go func2(&wg) wg.Wait() // Ожидание завершения всех Go рутин } func func1(wg *sync.WaitGroup) { // Код функции func1 wg.Done() // Уменьшение счетчика ожидания на 1 } func func2(wg *sync.WaitGroup) { // Код функции func2 wg.Done() // Уменьшение счетчика ожидания на 1 } |
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
var mutex sync.Mutex var counter int func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go increment(&wg) } wg.Wait() // Ожидание завершения всех Go рутин fmt.Println(counter) } func increment(wg *sync.WaitGroup) { mutex.Lock() // Блокировка доступа к общим данным counter++ mutex.Unlock() // Разблокировка доступа к общим данным wg.Done() } |
Это лишь некоторые возможности параллельных вычислений в Go. Всего лишь за ними следуют Go-средства для работы с параллельными вычислениями, такие как пулы горутин (goroutine pool
), пулы задач (task pools
), паттерны проектирования вроде потоковых каналов (streaming channels
) и другие.