Concurrency, Synchronization and Consistency. Пост №9. Примитивы синхронизации. Spinlock.
В прошлой части мы затронули основные фундаментальные моменты связанные с блокировками на уровне CPU. Теперь же погрузимся в детали. Из прошлого поста мы поняли что фундамент у блокировок - атомарные операции. Но что дальше? Какие варианты реализовать блокировку у нас есть? Сегодня рассмотрим один из вариантов - спинлок.
Spinlock - блокировка с активным ожиданием доступа к критическому участку кода. То есть поток не отпускает ядро процессора. Когда это бывает полезно? - в случаях когда мы явно знаем что пауза слишком короткая и цикл отпустить ядро - перейти в ожидание - вернуться в активное состояние будет дольше чем в бесконечном цикле дождаться доступа.
Спинлок является низкоуровневым примитивом синхронизации, реализовать его можно напрямую с помощью инструкций процессора, без системных вызовов ядра ОС. Чтобы его реализовать нам нужен доступ к атомарным инструкциям процессора в любимом языке программирования и переменная с возможными значениями 0 и 1.
Есть ли у такого подхода минусы? Да, они действительно есть.
- Активное ожидание подразумевает расход ресурсов. Если разработчик не рассчитал длительность блокировок в программе то спинлок будет утилизровать ресурсы в бесконечном цикле ожидания.
- Масштабируемость. Если в компьютер добавить больше ядер а в программу больше потоков то больше времени будет тратиться на инвалидацию кешей ядер процессора. Блокировка на уровне ОС станет предпочтительнее.
Базовый совет который дается во всех книжках и гайдах - используйте Mutex если не уверены нужен ли вам Спинлок. А если уверены, что нужен то зачем вам советы, пишите код😊
Примеры кода с спинлоками на языке C:
- Counter + Spinlock поверх stdatomic.h
- Counter + Spinlock поверх POSIX (pthread.h)
Post #401
1.52K

- 👍 7
- ❤ 3
- 🔥 2
- 🥱 2