Используйте примеры, чтобы лучше понять Mutex в Go

В Go каналы просто фантастические, и вы можете использовать их для связи между горутинами. Тем не менее, вы можете использовать sync.Mutex в некоторых случаях для удобства.

Эти обстоятельства подобны следующим:

  • Защита внутреннего состояния
  • Проблемы с кэшем
  • Для повышения эффективности

В этом посте я приведу три примера Go Mutex, и я надеюсь, что они помогут вам лучше понять реализацию Go Mutex.

Простой счетчик

В этом примере мы реализуем счетчик, который можно безопасно использовать одновременно. В частности, мы используем пять горутин для увеличения счетчика в 100 000 раз каждая. Затем мы печатаем окончательный счет.

Вот полный исходный код:

Конечный результат должен быть

500000

Пояснения:

  • Counter — это структура, содержащая переменную count и поле Mutex. Первая переменная хранит значение, которое увеличивается, а вторая обеспечивает правильное увеличение без проблем гонки данных.
  • Inc — это метод, который увеличивает счетчик на 1. В этом методе c.count++ — это критическая секция. Методы Lock и Unlock из мьютекса используются для того, чтобы только одна горутина могла одновременно выполнять коды критической секции.
  • Функция themain создает новый счетчик и запускает пять горутин. Горутины будут работать одновременно, и каждая из них будет выполняться 100 000 раз. Thewaitgroup используется для ожидания завершения всех горутин перед возвратом основной функции.

Игра в пинг-понг

В этом примере программа использует две горутины для имитации двух игроков. Каждый игрок ударяет по мячу десять раз. Программа использует мьютекс, чтобы гарантировать, что только одна горутина может получить доступ к мячу за раз и распечатать количество попаданий.

Вот полный исходный код:

Конечный результат должен быть

playerB 1
playerA 2
playerB 3
playerA 8
playerA 9   // notice here
...
playerB 18
playerA 19
playerB 20

Пояснения:

  • Тип Ball представляет собой структуру с полем hit и полем mutex. Первый используется для подсчета количества ударов по мячу, а второй гарантирует, что только одна горутина может получить доступ к мячу за раз.
  • b.hit++ — критическая секция. Метод блокировки и разблокировки гарантирует, что только одна горутина может выполнить критическую секцию.
  • В основной функции мы создаем шар и группу ожидания. Затем мы создаем две горутины. Они вызывают функцию игрока с именем своего игрока, мячом и группой ожидания. Наконец, мы вызываем метод ожидания группы ожидания для завершения обеих горутин.

Два игрока соревнуются, чтобы отбить мяч. Однако мы не гарантируем, что мяч попадет в чередующемся порядке.

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

  • передача права собственности на данные
  • распределение единиц работы
  • передача асинхронных результатов

Вот код для версии канала:

Самый простой кэш

Этот кеш имеет следующие методы; все они защищены мьютексом.

  • Set: добавить или обновить элемент в кеше
  • Get: получает элемент из кеша.
  • Delete : удаляет элемент из кеша.
  • Keys: получить все ключи в тайнике
  • Purge: удаляет все элементы в кеше

Краткое содержание

Mutex и Channel — это два разных инструмента для решения проблем с гонкой данных. Мьютекс последовательный доступ к ресурсу. С другой стороны, каналы предназначены для организации вычислений между горутинами.

Какой использовать?

Используйте наиболее выразительный и простой вариант!