Одна из проблем, с которыми я сталкивался несколько раз, - это избегать ошибок с многопоточными программами и блокировками.
Стоит ли использовать блокировки - это другой разговор. Есть много мест, где другие подходы, такие как каналы, могут быть намного проще для чтения и понимания.
Базовый пример моей проблемы можно увидеть ниже:
См. Комментарии «channel.mu must be hold». Чем сложнее логика, тем труднее будет обеспечить соблюдение этих комментариев. Это становится еще более сложным, когда у вас задействовано несколько блокировок.
Кроме того, на некоторых языках у вас нет средства проверки гонки или статики, поэтому простое решение - реализовать метод, который дает сбой, когда Mutex не удерживается должным образом. Фиксированный код будет выглядеть так:
Так как же нам это реализовать? Легко - отследить, кому принадлежит замок:
Код не совсем правильный (короткий период, когда MustOwn паникует неправильным сообщением), но он все же полезен и может находить ошибки. Для всей реализации нужен только способ идентификации текущего потока / горутины. В Go это немного проблематично, но выполнимо.
Также возникает вопрос, что мы делаем, когда хотим заблокировать, а затем передать мьютекс другому потоку без разблокировки. Проблему можно решить, реализовав метод Take, который меняет владельца.
Реализация не ограничивается Go и может быть легко повторно реализована на C, D или Delphi - на любых языках, которые вам нужно использовать.
Вот и все. Надеюсь, это кому-то поможет.