TGViewer
Евгений Козлов пишет про IT Евгений Козлов пишет про IT @careerunderhood · 2.84K subscribers
Post #402 2.01K
Concurrency, Synchronization and Consistency. Пост №10. Состояние гонки. Mutex.

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

Что такое Race Condition?
Race condition - ошибка проектирования многопоточной системы или приложения, при которой работа системы или приложения зависит от того, в каком порядке выполняются части кода. Своё название ошибка получила от похожей ошибки проектирования электронных схем.

Классический пример RC - работа с счетчиком из нескольких потоков. Без синхронизации и барьеров памяти. Более практиичный пример ситуации гонки - заказ товара через сайт (приложен к посту). Если не синхронизировать между собой участников системы то поведение программы может стать нежелательным (в случае магазина - можем напродавать товаров больше чем у нас физиечски есть).

Спинлоки разобранные вчера помогают решать подобные проблемы, но не лишены недостатков. Есть ли альтернатива спинлокам? Да, и это мьютексы.

Что такое Мьютекс?
Определение у мьютекса такое же как у спинлока, его цель - защита критической секции в коде. Но есть важный ньюанс - мьютекс передает управление потоком планировщику чтобы дать возможность другим потокам делать полезную работу (в отличии от спинлока который не отпускает ресурс и гоняет бесконечный цикл). Мьютекс в отличии спнлока пассивен и спит пока ждет своей очереди😊

Плюсы мьютекса:
- Экономия ресурса CPU по сравнению со спинлоком.

Минусы:
- В некоторых случаях будет медленнее чем спинлок, так как отпускать ресурс и возвращать его себе через планировщик будет дороже чем просто подержать.

Как я и говорил ранее - по умолчанию всегда стоит использовать именно его. В большинстве языков в публичное API выставлен именно mutex, чтобы найти spinlock нужно постараться.

Важный момент - функциональность блокировок практически во всех языках включает в себя не только активное / пассивное ожидание и гарантии эксклюзивного доступа, но и барьеры памяти. Именно поэтому нам как программистам явно не приходится объявлять их, мы работаем только с абстракцией блокировка, остальное от нас скрыто для нашего же спокойствия.

Пример кода в зависимости от архитектуры CPU инициирующего барьер.


static inline void memory_barrier(void)
{
#if defined(__x86_64__) || defined(__i386__)
__asm__ __volatile__("mfence" ::: "memory");
#elif defined(__aarch64__)
__asm__ __volatile__("dmb ish" ::: "memory");
#else
#error "Unsupported architecture"
#endif
}


Пример кода на языке С (pthread.h)
  • 🔥 6
  • 👍 2
More from @careerunderhood
  1. Oct 2, 2026Пока от темы Concurrency далеко не ушли. В последнем цикле я если и упоминал вопросы произ…
  2. Sep 30, 2026Результаты опроса меня впечатлили. Большинству интересны истории из работы. Поехали, начне…
  3. Sep 25, 2026Post #470
  4. Sep 21, 2026Concurrency, Synchronization and Consistency. Non-blocking. Оглавление Введение - Блокирую…
  5. Sep 21, 2026Concurrency and Consistency. Non-blocking, lock-free and async. Пост №12. Заключение. Когд…
  6. Sep 20, 2026Concurrency and Consistency. Non-blocking, lock-free and async. Пост №11. Самые важные фак…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →