← Все этапы
04 · ИНЖЕНЕРИЯУрок 10 из 1250 мин

Синхронизация и тесты

Согласуем конкурентную работу и закрепляем поведение автоматическими проверками.

Координация важнее числа горутин

Если несколько горутин изменяют общее состояние, нужен механизм синхронизации. Канал может доставлять частичные итоги владельцу результата; WaitGroup полезен, когда важно дождаться завершения всех работников.

package main

import (
	"fmt"
	"sync"
)

func runeCount(text string) int { return len([]rune(text)) }

func main() {
	words := []string{"go", "мир"}
	results := make(chan int, len(words))
	var workers sync.WaitGroup
	for _, word := range words {
		workers.Add(1)
		go func(value string) {
			defer workers.Done()
			results <- runeCount(value)
		}(word)
	}
	workers.Wait()
	close(results)
	total := 0
	for count := range results {
		total += count
	}
	fmt.Println("символов:", total)
}

WaitGroup сигнализирует о завершении группы горутин. Для общего счётчика нужна защита от одновременной записи; альтернативно работники отправляют частичные ответы через канал. Тестируйте функцию подсчёта отдельно от ввода.

Практика

Попробуйте сами

Создайте функцию подсчёта Unicode-символов и обработайте в отдельных горутинах слова go и мир. Соберите оба результата без общего изменяемого счётчика. Табличными тестами проверьте "" → 0, "Go" → 2 и "мир" → 3; запустите go test -race ./....

Проверка результата

Как понять, что получилось

Тесты для пустой строки, ASCII-слова и мир проходят; сумма длин слов go и мир равна 5 символам (пробел не считается), go test -race ./... не находит гонок.

Синхронизация и тесты | Go | WebSchool · Go