Е
Евгений Козлов пишет про IT
@careerunderhood2.7K подп.
1.7Kпросмотров
64.9%от подписчиков
15 декабря 2025 г.
📷 ФотоScore: 1.9K
Concurrency, Synchronization and Consistency. Пост №19. Синхронизация в read-heavy сценариях. Read-Write Mutexes. В прошлом посте мы познакомились с sync.Mutex в Go - примитивом рантайма обеспечивающим взаимное исключение. Он умный, у него как и у мьютекса ОС есть fast path / slow path. Кажется что все хорошо. Но есть задача с которой классическому мьютексу справляться тяжеловато. Сделаем шаг назад и вспомним - зачем вообще нужна синхронизация? Все дело в том что нам нужно корректно рапространять ко всем потокам нашей программы события об изменении данных в памяти. Для этого нужны атомики, барьеры памяти. Если мы не будем синхронизироваться то каждый участник будет работать со своей копией данных, и перетирать друг друга, получая на выходе мусор. Представим ситуацию, когда в нашей программе нет операций записи, а только чтение? Здравый смысл говорит нам что тогда нам вообще не нужны никакие примитивы - операции чтения являются потокобезопасными, не нужно ничего выдумывать. А что если операции записи есть, но они редкие? Раз в минуту например? Или например 1 операция записи на 1000 чтений? Будет ли эффективной реализация когда мы защитимся обычным мьютексом? В общем случае нет, об эффективности речи быть и не может. Потому что мы будем работать в режиме не только эксклюзивной записи но и эксклюзивного чтения. Но ведь можем лучше, компьютер нас не ограничивает в параллельном чтении. Для решения такой задачи были придуманы особенные примитивы синхронизации. Обычно с префиксом read-write в названии. Примеры: - pthread_rwlock_t в POSIX - Read-Copy-Update, RCU в Linux - sync.RWMutex в Golang - ReentrantReadWriteLock в Java Они реализованы внутри как связка обычного mutex и atomic переменных, ведущим учет читателей. Также важно отметить, что в языках в отличии от ОС эти примитивы могут не маппиться напрямую на примитивы ОС, потому что например в том же Go свои горутины, рантайм, и модель памяти. Примитив синхронизации должен им соответствовать. sync.RWMutex реализован на чистом Go с вкраплениями internal вызовов, можете проверить самостоятельно. Семантика read-write блокировок Концептуально такой мьютекс может вести себя одним из 3х способов: - Пока память открыта на чтение, давать читателям беспрепятственный доступ. Писатели могут ждать сколько угодно. - Как только появился хоть один писатель, никого больше не пускать. Все остальные могут простаивать. - Не допускать простоев. Другими словами: независимо от действий других потоков, читатель или писатель должен пройти барьер за конечное время. О том как достигать тех или иных гарантий поговорим отдельно. На сегодня всё, в следующих постах поговорим о цене которую мы платим используя такой примитив, а также посмотрим на бенчмарках насколько оправдано его использование, возможны ли ситуации когда он делает только хуже. ----- Если вам понравился пост, поддержите его реакциями и комментариями. Мне важно увидеть вашу обратную связь. Спасибо! 📖 Оглавление
1.7K
просмотров
2959
символов
Нет
эмодзи
Да
медиа

Другие посты @careerunderhood

Все посты канала →
Concurrency, Synchronization and Consistency. Пост №19. Синх — @careerunderhood | PostSniper