Атомики в Go - это один из методов синхронизации горутин. Они находятся в пакете стандартной библиотеки sync/atomic. Некоторые статьи сравнивают atomics с mutex, так как это примитивы синхронизации низкого уровня. Они предоставляют бенчмарки и сравнения по скорости, например Go: How to Reduce Lock Contention with the Atomic Package.
Рубрика «Mutex»
Атомики в Go: особенности внутренней реализации
2023-06-30 в 15:10, admin, рубрики: assembly, atomic, atomics, backend, concurrency, Go, golang, MutexПочему мьютексы в Rust реализованы именно так
2022-04-08 в 7:34, admin, рубрики: Mutex, Rust, многопоточное программирование, многопоточность, мьютексы, параллельное программирование, ПрограммированиеЯ часто слышу от пробующих работать с Rust системных программистов жалобы на мьютексы и особенно на Rust Mutex API. Жалобы обычно выглядят так:
- Они не хотят, чтобы мьютекс содержал данные, только блокировку.
- Они не хотят управлять «защитным» значением, разблокирующим мьютекс при сбросе, в частности, они просто хотят вызывать операцию
unlock
, потому что им кажется, что это более явное действие.
Такие изменения превратили бы Rust mutex API в эквивалент C/Posix mutex API. Однажды я даже видел, как один разработчик пытался использовать Mutex<()>
и разные хитрости, чтобы его имитировать.
Однако у такого стремления есть проблема: эти два аспекта Mutex
неразрывно связаны друг с другом, а также с гарантиями безопасности Rust в целом — изменение одного из них или обоих откроет возможности для возникновения незаметных багов и повреждений из-за гонок данных.
Использование API мьютексов в стиле C, состоящего из набора косвенно защищаемых данных и из функций lock
и unlock
было бы опрометчивым в Rust, потому что это позволяет безопасному коду легко вносить ошибки, нарушающие безопасность памяти и вызывающие гонки данных.
Прозвучит спорно, но я утверждаю, что это справедливо и для C. Просто в Rust это более очевидно, поскольку Rust тщательно разделяет понятия «безопасного» кода, в который невозможно внести подобные ошибки, и «небезопасного» кода, в который можно вносить такие ошибки. В C такого разделения нет, и в результате этого использующий мьютексы код на C может тривиальным образом создавать серьёзные баги, которые потенциально можно подвергать эксплойтам.
В этом посте я разберу типичный C mutex API, сравню его с типичным Rust mutex API, и расскажу о том, что произойдёт, если мы изменим Rust API так, чтобы он напоминал C.
Читать полностью »
Корутины и синхронизация. Лучше не смешивать
2020-11-19 в 9:39, admin, рубрики: concurrency, coroutines, funcorp, kotlin, multithreading, Mutex, synchronized, syncronize, Блог компании FunCorp, ПрограммированиеПредположим, у вас в коде есть критическая секция, которая не должна выполняться более, чем одним потоком одновременно.
В мире Java одним из стандартных решений является добавление ключевого слова synchronized
к сигнатуре метода. В Kotlin для получения того же эффекта используется аннотация @Synchronized
Читать полностью »
Deadlock Empire — игра для разработчиков
2020-02-14 в 8:15, admin, рубрики: .net, avanpost, C#, concurrency, multithreading, Mutex, parallel programming, semaphore, Блог компании Avanpost, Игры и игровые приставки, многопоточность, Программирование
Хабр, как известно, не место для игр, но мы нашли одно исключение, которое, как нам кажется, достойно упоминания здесь!
Встречайте: Deadlock Empire!
Суть игры — управление планировкой потоков, код которых приведен в заданиях. Управлять нужно так, чтобы добиться ошибочной ситуации: взаимблокировки, повторных значений счетчиков, достижения определенных участков кода и прочих непредвиденных ситуаций, которые нужно осознавать при разработке многопоточных приложений.
Читать полностью »
Разбираемся с новым sync.Map в Go 1.9
2017-09-26 в 0:50, admin, рубрики: cache contention, Go, map, Mutex, rwmutex, syncОдним из нововведений в Go 1.9 было добавление в стандартную библиотеку нового типа sync.Map, и если вы ещё не разобрались что это и для чего он нужен, то эта статья для вас.
Для тех, кому интересен только вывод, TL;DR:
если у вас высоконагруженная (и 100нс решают) система с большим количеством ядер процессора (32+), вы можете захотеть использовать sync.Map вместо стандартного map+sync.RWMutex. В остальных случаях, sync.Map особо не нужен.
Если же интересны подробности, то давайте начнем с основ.
Обзор примитивов синхронизации — спинлоки и тайны ядра процессора
2016-03-06 в 11:15, admin, рубрики: atomic, Mutex, spinlock, программирование микроконтроллеров, системное программирование, метки: spinlockПоследняя статья про классические примитивы синхронизации.
(Наверное, потом напишу ещё одну про совсем уже нетипичную задачу, но это потом.)
Сегодня мы немножко заглянем в процессор. Чуть-чуть.
По сути, мы будем говорить про единственный примитив, который принципиально отличается от остальных: спинлок. Spinlock.
В комментариях к предыдущим заметкам возникла дискуссия — насколько справедливо вообще выделять спинлок как примитив, ведь по сути он — просто мьютекс, верно? Он выполняет ту же функцию — запрещает одновременное исполнение фрагмента кода несколькими параллельными нитями.
На уровне процесса всё так и есть — различия между спинлоком и мьютексом — чисто технические, вопрос реализации и производительности.
Но меня эта тема интересует не только с позиции программиста юзерленда, но и с позиции разработчика ядра, а так же и разработчика самих примитивов синхронизации. И тут уже различие принципиально.
Дело в том, что внутри ядра мьютекс реализован с помощью спинлоков, а вот спинлоки реализованы сами по себе, автономно. Они — действительно базовый примитив. Ниже — только сам процессор.
Есть и ещё одно, семантическое различие. Мьютекс допускает и предполагает снятие нити с процессора, долгую остановку вызывающей нити. Мьютексом можно запереть объект на час или сутки, это приемлемо и нормально. Спинлок принципиально рассчитан только на кратчайшие приостановки, это всегда работа с неатомарным стейтом объекта. Присваивание группы переменных, небольшой цикл — это максимум того, что можно сделать под спинлоком.
Итак, иерархия реализации такова: mutex/cond/sema сделаны на базе спинлоков, спинлоки — на базе атомарных операций, предоставляемых процессором. Мы в них немного заглянем сегодня.
Как устроен спинлок?
Читать полностью »
Обзор примитивов синхронизации
2016-03-03 в 14:03, admin, рубрики: condition variables, Mutex, semaphore, spinlock, Программирование, программирование микроконтроллеров, системное программированиеСинхронизация нужна в любой малтитредной программе. (Если, конечно, она не состоит из локлесс алгоритмов на 100%, что вряд ли). Будь то приложение или компонента ядра современной операционной системы.
Меня всё нижесказанное, конечно, больше волнует с точки зрения разработки ядра ОС. Но почти всё применимо и к пользовательскому коду.
Кстати, ядра старых ОС в примитивах синхронизации не нуждались, поскольку преемптивной мультизадачности внутри ядра в старые добрые времена не было. (Уж за Юникс 7-й версии я отвечаю. Не было.) Точнее, единственным методом синхронизации был запрет прерываний. Но об этом позже.
Сначала перечислим героев. Мне известны следующие примитивы синхронизации:
User/kernel mode: mutex+cond, sema, enter/leave critical section.
Kernel only: spinlock, управление прерываниями.
Зачем всё это нужно, читатель, наверное, знает, но всё же уточним.
Если некоторая структура данных может быть доступна двум параллельно работающим нитям (или нити и прерыванию), и являет собой сущность, к которой нельзя обеспечить атомарный доступ, то работу с такой структурой нужно производить так, чтобы только одна нить одновременно выполняла сложные манипуляции состоянием структуры.
Читать полностью »
Мьютексы в стиле Rust для C++
2014-09-24 в 7:43, admin, рубрики: c++, c++11, multithreading, Mutex, Rust, synchronization, template, templates, Программирование, С++Здравствуй!
Я часто разрабатываю программы на C++ и люблю этот язык, что бы о нём ни говорили. Наверное потому, что во многих областях замены ему пока что нет. Однако язык этот, как все мы знаем, не лишён недостатков, и поэтому я всегда с интересом слежу за новыми подходами, паттернами или даже языками программирования, призванными решить какую-то часть этих проблем.
Так, недавно, я с интересом просматривал презентацию Степана Кольцова о языке программирования Rust, и мне очень понравилась идея реализации мьютаксов в этом языке. Причём никаких препятствий для реализации подобного примитива в C++ я не увидел и сразу же открыл IDE, с целью реализовать подобное на практике.
Читать полностью »
Реализация мьютекса вне ОС на примере микроконтроллера AVR и шины TWI
2013-09-12 в 9:30, admin, рубрики: avr, diy или сделай сам, Mutex, Программинг микроконтроллеров, метки: avr, mutexРешил однажды для себя я соорудить погодную станцию. Датчики там разные, в том числе на шине I2C. И как годится, обычно вначале, сделал все на флагах ожидания. Но путь настоящего джедая иной, и было решено все повесить на прерывания. Вот тут и начался геморрой. Проблема, с которой я столкнулся это обработка нескольких подряд идущих запросов. Например датчик давления BMP085 для дальнейшей работы с ним, требует вытянуть из его EEPROM 11 калибровочных констант:
О том как я пришел к решению и последовательность хода мыслей изложены ниже.
Читать полностью »
Потоки, блокировки и условные переменные в C++11 [Часть 2]
2013-06-08 в 18:41, admin, рубрики: c++, c++11, condition variables, deadlocks, locks, Mutex, threads, windows, блокировки, взаимоблокировки, все равно никто не читает метки, мьютекс, потоки, Программирование, условные переменные, метки: c++, c++11, condition variables, deadlocks, locks, mutex, threads, блокировки, взаимоблокировки, все равно никто не читает метки, мьютекс, потоки, условные переменные Для более полного понимания этой статьи, рекомендуется прочитать ее первую часть, где основное внимание было уделено потокам и блокировкам, в ней объяснено много моментов (терминов, функций и т.д.), которые без пояснения будут использованы здесь.
В данной статье будут рассмотрены условные переменные… Читать полностью »