Изменения

Перейти к: навигация, поиск

Стек Трайбера

947 байт добавлено, 19:19, 4 сентября 2022
м
rollbackEdits.php mass rollback
{{В разработке}}
'''Стек Трайбера''' (англ. ''(Treiber Stack)'' ) — масштабируеммый стек без блокировок (англ. ''lock-free'' стек). Считается, что впервые данный алгоритм был опубликовал R. Kent Treiber<ref>[http://domino.research.ibm.com/library/cyberdig.nsf/0/58319a2ed2b1078985257003004617ef?OpenDocument R. Kent Treiber {{---}} Systems Programming: Coping with Parallelism, 1968]</ref>. Алгоритм использует примитив <tex>CAS</tex> (''(compare and set)'').
== Описание ==
=== Идея Требования к алгоритму ===Основное отличие Treiber stack стека Трайбера от однопоточного случая заключается в том, что несколько потоков имеют доступ к данным в стеке одновременно, а значит, могут удалять и добавлять элементы. Чтобы не получилась каша, хотелось бы Необходимо как-то контролировать процесс взаимодействия потоков. Для этого введем следующие условия:#Добавлять новый элемент только если увереныКонечно, это можно было бы сделать, просто блокируя каждую операцию, что добавляемый элемент — единственный с момента начала операциипроизводимую на стеке.#При удалении элементаНо такая блокировка уменьшает параллелизм, перед его возвратома значит, нужно быть увереннымуменьшаем масштабируемость программы. Уходя от данной стратегии,что никакой другой поток не добавил новый элемент в стек с начала операцииразрешим потокам работать одновременно со стеком и потребуем от алгоритма условие неблокируемости.=== Lock-freedom free алгоритмы и CAS ===Для многопоточного алгоритма недостаточно требовать лишь взаимное исключениеСвойство неблокируемости (англ. Другое важное свойство — неблокируемость. Свойство ''Lock-freedom'' ) гарантирует прогресс в системе. Для его реализации используется операция <tex>CAS</tex>.
{{Определение
|definition=
'''Сравнение с обменом''' (англ. ''compare and set, compare and swap, CAS'') — атомарная инструкция, сравнивающая значение в памяти с одним из аргументовпервым аргументом и, и в случае успеха , записывающая второй аргумент в память.
}}
Ниже представлен псевдокод операции <tex>CAS</tex>для целочисленных переменных'''fun ''' cas('''int*''' p, '''int''' old, '''int''' new): '''bool {''' '''if ''' *p != old { '''return ''' '''false }''' *p = new '''return ''' '''true''' }<tex>CAS</tex> используется для реализации таких примитивов синхронизации, как ''mutex'' и ''semaphore''. Это своеобразный базовый "кирпичик" для ''Lock-freedomfree'' алгоритмов, ведь если <tex>CAS</tex> привел к неудачинеудаче, то кто-то другой поток изменил старое значение. Таким образом, прогресс в системе есть. <tex>CAS</tex> реализован на уровне атомарных переменных во многих языках программирование, в том числе Java и Cпрограммирования.
== Алгоритм ==
 
=== Идеи ===
Переходя от требований к конкретной реализации, введем следующие условия:
#Добавлять новый элемент только убедившись, что на момент окончания операции, указатель на голову стека остался тот же. Другими словами, элемент, выбранный нами в качестве <tex>next</tex>, на момент окончания операции все еще актуален.
#При удалении элемента, перед его возвратом, нужно быть уверенным, что мы действительно удаляем текущую голову стека и в качестве новой головы предъявляем <tex>H.next</tex>.
 
=== Структура стека ===
Как всегда , каждый элемент стека содержит информацию о хранимом значении (<tex>value</tex>) и указатель на следующий элемент(<tex>next</tex>). Также имеем указатель на голову стека <tex>H</tex>, который будем изменять при помощи операции <tex>CAS</tex>. Если при этом голова указывает на <tex>H==null</tex>, то стек — пуст. 
=== Удаление элементов ===
Запомним, на что указывает голова стека (запишем в локальную переменную <tex>head</tex>). Значение, которое хранит в себе <tex>head</tex>, — то, что необходимо будет вернуть. Попробуем переместить голову стеком <tex>CAS</tex>ом. Если удалось — вернем <tex>head.value</tex>. Если нет, то это означает, что с момента начала операции стек был изменен. Поэтому попробуем проделать операцию заново.
<references />
 
==См. также==
* [[Алгоритмы_взаимного_исключения]]
 
== Источники информации==
* [https://en.wikipedia.org/wiki/Treiber_Stack Wikipedia Treiber {{---}} Stack]
1632
правки

Навигация