[БЕЗ_ЗВУКА] В предыдущем примере мы разобрали mutex как средство для избегания гонки, когда мы работаем с одной переменной из разных системных потоков. В этом примере мы разберем примитив под названием atomic. Дело в том, что mutex — это такой большой, «жирный» примитив, большая, «жирная» конструкция для синхронизации мощных кусков. Но иногда нам бывает нужно всего лишь атомарно инкрементировать просто переменную. Давайте начнем с примера. У нас есть программа, которая запускает тысячу горутин. Каждая горутина просто увеличивает счетчик. Мы ожидаем, что по результатам работы программы в нашем счетчике будет 1000. Однако из-за того, что счетчики инкрементируются из разных горутин, это будет не так. Для начала давайте запустим. Итак, у нас получилось всего 950, хотя горутин была вызвана тысяча. Получилось это потому, что, как я уже говорил, мы инкрементировали этот счетчик их разных горутин и попали как раз на состояние гонки. Как сделать атомарный счетчик? Для этого пользуемся атомиком из пакета, как ни странно, sync/atomic. Итак, нам нужно подрубить этот пакет, и теперь мы уже не инкрементируем счетчик напрямую, а используем функцию из этого пакета, то есть из пакета atomic. Мы вызываем функцию AddInt32, куда передаем адрес нашей переменной и то значение, на которое мы хотим увеличить. Больше ничем программа не отличается. Давайте ее запустим. Отлично! Мы получили ожидаемый результат, что количество операций, которое выдала нам программа, равно 1000. Atomic быстрее мьютекса. На самом деле внутри мьютекса встроен atomic как более низкоуровневый примитив. В пакете atomic довольно много разных функций для атомарных операций со счетчиками либо для сравнения и замены. Если вы активно занимаетесь многопроцессорной разработкой, то очень рекомендуется посмотреть и знать, что он может.