<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.156.58&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.156.58&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/217.66.156.58"/>
		<updated>2026-07-20T23:09:21Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D1%82%D0%B5%D0%BA_%D0%A2%D1%80%D0%B0%D0%B9%D0%B1%D0%B5%D1%80%D0%B0&amp;diff=66329</id>
		<title>Стек Трайбера</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D1%82%D0%B5%D0%BA_%D0%A2%D1%80%D0%B0%D0%B9%D0%B1%D0%B5%D1%80%D0%B0&amp;diff=66329"/>
				<updated>2018-10-01T07:44:56Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.58: /* Lock-freedom алгоритмы и CAS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Стек Трайбера''' ''(Treiber Stack)'' —  масштабируеммый ''lock-free'' стек. Считается, что впервые данный алгоритм был опубликовал R. Kent Treiber&amp;lt;ref&amp;gt;[http://domino.research.ibm.com/library/cyberdig.nsf/0/58319a2ed2b1078985257003004617ef?OpenDocument R. Kent Treiber {{---}} Systems Programming: Coping with Parallelism, 1968]&amp;lt;/ref&amp;gt;. Алгоритм использует примитив &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; ''(compare and set)''.&lt;br /&gt;
== Описание ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Основное отличие Treiber stack от однопоточного случая заключается в том, что несколько потоков имеют доступ к данным в стеке одновременно, а значит, могут удалять и добавлять элементы. Чтобы не получилась каша, хотелось бы как-то контролировать процесс взаимодействия потоков. Для этого введем следующие условия:&lt;br /&gt;
#Добавлять новый элемент только если уверены, что добавляемый элемент — единственный с момента начала операции.&lt;br /&gt;
#При удалении элемента, перед его возвратом, нужно быть уверенным,что никакой другой поток не добавил новый элемент в стек с начала операции.&lt;br /&gt;
=== Lock-freedom алгоритмы и CAS ===&lt;br /&gt;
Для многопоточного алгоритма недостаточно требовать лишь взаимное исключение. Другое важное свойство — неблокируемость. Свойство ''Lock-freedom'' гарантирует прогресс в системе. Для его реализации используется операция &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
'''Сравнение с обменом''' (англ. ''compare and set, compare and swap, CAS'') — атомарная инструкция, сравнивающая значение в памяти с одним из аргументов, и в случае успеха записывающая второй аргумент в память.&lt;br /&gt;
}}&lt;br /&gt;
Ниже представлен псевдокод операции &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; для целочисленных переменных.&lt;br /&gt;
&lt;br /&gt;
 '''fun''' cas('''int*''' p, '''int''' old, '''int''' new): '''bool'''&lt;br /&gt;
     '''if''' *p != old &lt;br /&gt;
         '''return''' '''false'''&lt;br /&gt;
     *p = new&lt;br /&gt;
     '''return''' '''true'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;  используется для реализации таких примитивов синхронизации, как ''mutex'' и ''semaphore''. Это своеобразный базовый &amp;quot;кирпичик&amp;quot; для ''Lock-freedom'' алгоритмов, ведь если &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; привел к неудачи, то кто-то другой изменил старое значение. Таким образом, прогресс в системе есть. &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; реализован на уровне атомарных переменных во многих языках программирование, в том числе Java и C.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм == &lt;br /&gt;
=== Структура стека ===&lt;br /&gt;
Как всегда каждый элемент стека содержит информацию о хранимом значении и указатель на следующий элемент. Также имеем указатель на голову стека &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, который будем изменять при помощи операции &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;H==null&amp;lt;/tex&amp;gt;, то стек — пуст.&lt;br /&gt;
=== Удаление элементов ===&lt;br /&gt;
Запомним, на что указывает голова стека (запишем в локальную переменную &amp;lt;tex&amp;gt;head&amp;lt;/tex&amp;gt;). Значение, которое хранит в себе &amp;lt;tex&amp;gt;head&amp;lt;/tex&amp;gt;, — то, что необходимо будет вернуть. Попробуем переместить голову стеком &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;ом. Если удалось — вернем &amp;lt;tex&amp;gt;head.value&amp;lt;/tex&amp;gt;. Если нет, то это означает, что с момента начала операции стек был изменен. Поэтому попробуем проделать операцию заново.&lt;br /&gt;
&lt;br /&gt;
=== Добавление элементов ===&lt;br /&gt;
Запомним, куда указывает голова стека (запишем в локальную переменную &amp;lt;tex&amp;gt;head&amp;lt;/tex&amp;gt;). Создадим новый элемент, который хотим добавить в начало стека. Указатель на следующее значение для него — &amp;lt;tex&amp;gt;head&amp;lt;/tex&amp;gt;. Попробуем переместить &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на новый элемент, при помощи &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;. Если это удалось — добавление прошло успешно. Если нет, то кто-то другой изменил стек, пока мы пытались добавить элемент. Придется начинать сначала.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
 '''fun''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true''') &amp;lt;font color=green&amp;gt;//Cas loop&amp;lt;/font&amp;gt;&lt;br /&gt;
       head = H&lt;br /&gt;
       '''if''' (CAS (&amp;amp;H, head, head.next)) &lt;br /&gt;
         '''return''' head.value&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 '''fun''' push(x: '''Int''')&lt;br /&gt;
     '''while''' ('''true''') &amp;lt;font color=green&amp;gt;//Cas loop&amp;lt;/font&amp;gt;&lt;br /&gt;
       head = H&lt;br /&gt;
       '''if''' (head == null)&lt;br /&gt;
         '''throw''' new EmptyStackException();&lt;br /&gt;
       newHead = Node {value: x, next: head}&lt;br /&gt;
       '''if''' (CAS (&amp;amp;H, head, newHead)) &lt;br /&gt;
         '''return'''&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Treiber_Stack Wikipedia Treiber {{---}} Stack]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Compare-and-swap Wikipedia {{---}} CAS]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>217.66.156.58</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D1%82%D0%B5%D0%BA_%D0%A2%D1%80%D0%B0%D0%B9%D0%B1%D0%B5%D1%80%D0%B0&amp;diff=66328</id>
		<title>Стек Трайбера</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D1%82%D0%B5%D0%BA_%D0%A2%D1%80%D0%B0%D0%B9%D0%B1%D0%B5%D1%80%D0%B0&amp;diff=66328"/>
				<updated>2018-10-01T07:33:01Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.58: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Стек Трайбера''' ''(Treiber Stack)'' —  масштабируеммый ''lock-free'' стек. Считается, что впервые данный алгоритм был опубликовал R. Kent Treiber&amp;lt;ref&amp;gt;[http://domino.research.ibm.com/library/cyberdig.nsf/0/58319a2ed2b1078985257003004617ef?OpenDocument R. Kent Treiber {{---}} Systems Programming: Coping with Parallelism, 1968]&amp;lt;/ref&amp;gt;. Алгоритм использует примитив &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; ''(compare and set)''.&lt;br /&gt;
== Описание ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Основное отличие Treiber stack от однопоточного случая заключается в том, что несколько потоков имеют доступ к данным в стеке одновременно, а значит, могут удалять и добавлять элементы. Чтобы не получилась каша, хотелось бы как-то контролировать процесс взаимодействия потоков. Для этого введем следующие условия:&lt;br /&gt;
#Добавлять новый элемент только если уверены, что добавляемый элемент — единственный с момента начала операции.&lt;br /&gt;
#При удалении элемента, перед его возвратом, нужно быть уверенным,что никакой другой поток не добавил новый элемент в стек с начала операции.&lt;br /&gt;
=== Lock-freedom алгоритмы и CAS ===&lt;br /&gt;
Для многопоточного алгоритма недостаточно требовать лишь взаимное исключение. Другое важное свойство — неблокируемость. Свойство ''Lock-freedom'' гарантирует прогресс в системе. Для его реализации используется операция &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
'''Сравнение с обменом''' (англ. ''compare and set, compare and swap, CAS'') — атомарная инструкция, сравнивающая значение в памяти с одним из аргументов, и в случае успеха записывающая второй аргумент в память.&lt;br /&gt;
}}&lt;br /&gt;
Ниже представлен псевдокод операции &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 fun cas(p, old, new): bool {&lt;br /&gt;
     if *p ≠ old {&lt;br /&gt;
         return false&lt;br /&gt;
     }&lt;br /&gt;
     *p ← new&lt;br /&gt;
     return true&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;  используется для реализации таких примитивов синхронизации, как ''mutex'' и ''semaphore''. Это своеобразный базовый &amp;quot;кирпичик&amp;quot; для ''Lock-freedom'' алгоритмов, ведь если &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; привел к неудачи, то кто-то другой изменил старое значение. Таким образом, прогресс в системе есть. &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; реализован на уровне атомарных переменных во многих языках программирование, в том числе Java и C.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм == &lt;br /&gt;
=== Структура стека ===&lt;br /&gt;
Как всегда каждый элемент стека содержит информацию о хранимом значении и указатель на следующий элемент. Также имеем указатель на голову стека &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, который будем изменять при помощи операции &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;H==null&amp;lt;/tex&amp;gt;, то стек — пуст.&lt;br /&gt;
=== Удаление элементов ===&lt;br /&gt;
Запомним, на что указывает голова стека (запишем в локальную переменную &amp;lt;tex&amp;gt;head&amp;lt;/tex&amp;gt;). Значение, которое хранит в себе &amp;lt;tex&amp;gt;head&amp;lt;/tex&amp;gt;, — то, что необходимо будет вернуть. Попробуем переместить голову стеком &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;ом. Если удалось — вернем &amp;lt;tex&amp;gt;head.value&amp;lt;/tex&amp;gt;. Если нет, то это означает, что с момента начала операции стек был изменен. Поэтому попробуем проделать операцию заново.&lt;br /&gt;
&lt;br /&gt;
=== Добавление элементов ===&lt;br /&gt;
Запомним, куда указывает голова стека (запишем в локальную переменную &amp;lt;tex&amp;gt;head&amp;lt;/tex&amp;gt;). Создадим новый элемент, который хотим добавить в начало стека. Указатель на следующее значение для него — &amp;lt;tex&amp;gt;head&amp;lt;/tex&amp;gt;. Попробуем переместить &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на новый элемент, при помощи &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt;. Если это удалось — добавление прошло успешно. Если нет, то кто-то другой изменил стек, пока мы пытались добавить элемент. Придется начинать сначала.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
 '''fun''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true''') &amp;lt;font color=green&amp;gt;//Cas loop&amp;lt;/font&amp;gt;&lt;br /&gt;
       head = H&lt;br /&gt;
       '''if''' (CAS (&amp;amp;H, head, head.next)) &lt;br /&gt;
         '''return''' head.value&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 '''fun''' push(x: '''Int''')&lt;br /&gt;
     '''while''' ('''true''') &amp;lt;font color=green&amp;gt;//Cas loop&amp;lt;/font&amp;gt;&lt;br /&gt;
       head = H&lt;br /&gt;
       '''if''' (head == null)&lt;br /&gt;
         '''throw''' new EmptyStackException();&lt;br /&gt;
       newHead = Node {value: x, next: head}&lt;br /&gt;
       '''if''' (CAS (&amp;amp;H, head, newHead)) &lt;br /&gt;
         '''return'''&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Treiber_Stack Wikipedia Treiber {{---}} Stack]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Compare-and-swap Wikipedia {{---}} CAS]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>217.66.156.58</name></author>	</entry>

	</feed>