Are & # 8220; Benaphores & # 8221; стоит реализовать на современных ОС?

StackOverflow https://stackoverflow.com/questions/1635416

Вопрос

В свое время программистом на BeOS я прочитал эта статья Бенуа Шиллингса, описывающая, как создать" benaphore ": метод использования атомарной переменной для принудительного применения критического раздела, который устраняет необходимость в получении / освобождении мьютекса в общем (нет спор) дело.

Я подумал, что это довольно умно, и кажется, что вы могли бы сделать такой же трюк на любой платформе, которая поддерживает atomic-increment / decment.

С другой стороны, это похоже на то, что с такой же легкостью может быть включено в саму стандартную реализацию мьютекса ... в этом случае реализация этой логики в моей программе будет избыточной и не даст никакой выгоды.

Кто-нибудь знает, используют ли современные трюки современные API блокировки (например, pthread_mutex_lock () / pthread_mutex_unlock ())? А если нет, то почему?

Это было полезно?

Решение

То, что описывает ваша статья, сегодня широко используется. Чаще всего это называется " критический раздел " ; и он состоит из взаимосвязанной переменной, набора флагов и внутреннего объекта синхронизации (Mutex, если я правильно помню). Как правило, в сценариях с небольшим количеством конфликтов критический раздел выполняется полностью в пользовательском режиме, без участия объекта синхронизации ядра. Это гарантирует быстрое выполнение. Когда конкуренция высока, объект ядра используется для ожидания, что освобождает временной интервал, проводящий для более быстрого оборота.

Как правило, в настоящее время очень мало смысла в реализации примитивов синхронизации. Операционные системы поставляются с большим разнообразием таких объектов, и они оптимизированы и протестированы в значительно более широком диапазоне сценариев, чем может себе представить один программист. Буквально годы требуются, чтобы изобрести, внедрить и протестировать хороший механизм синхронизации. Это не значит, что в попытках нет смысла :)

Другие советы

Java AbstractQueuedSynchronizer (и его брат AbstractQueuedLongSynchronizer ) работает аналогично, или, по крайней мере, его можно реализовать аналогичным образом. Эти типы формируют основу для нескольких примитивов параллелизма в библиотеке Java, таких как ReentrantLock и FutureTask .

Он работает посредством использования атомарного целого числа для представления состояния. Блокировка может определить значение 0 как разблокированное и 1 как заблокированное. Любой поток, желающий получить блокировку, пытается изменить состояние блокировки с 0 на 1 с помощью атомарной операции сравнения-и-установки ; если попытка не удалась, текущее состояние не равно 0, что означает, что блокировка принадлежит другому потоку.

AbstractQueuedSynchronizer также облегчает ожидание блокировок и уведомление о условиях , поддерживая очереди CLH , которые являются связанными без блокировок списками, представляющими строку потоки, ожидающие либо получения блокировки, либо получения уведомления через условие. Такое уведомление перемещает один или все потоки, ожидающие в состоянии, в начало очереди тех, кто ожидает получения связанной блокировки.

Большая часть этого механизма может быть реализована в виде атомного целого числа, представляющего состояние, а также пары атомных указателей для каждой очереди ожидания. Фактическое планирование того, какие потоки будут бороться за проверку и изменение переменной состояния (например, через AbstractQueuedSynchronizer # tryAcquire (int) ) выходит за рамки такой библиотеки и попадает в хост-систему планировщик.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top