<?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=139.45.249.101&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=139.45.249.101&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/139.45.249.101"/>
		<updated>2026-06-11T14:27:39Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=2_Phase_Locking&amp;diff=81137</id>
		<title>2 Phase Locking</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=2_Phase_Locking&amp;diff=81137"/>
				<updated>2021-07-16T16:06:00Z</updated>
		
		<summary type="html">&lt;p&gt;139.45.249.101: Убрал лишнее слово&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория: Параллельное программирование]]&lt;br /&gt;
'''Алгоритм двухфазной блокировки''' используется для взятия блокировок при выполнении [[Транзакции в распределённых системах|распределённых транзакций]] (например, в СУБД).&lt;br /&gt;
&lt;br /&gt;
Алгоритм требует, чтобы каждая транзакция состояла из двух фаз: на первой мы только набираем блокировки (в любом порядке), а на второй фазе мы их только отпускаем (в любом порядке).&lt;br /&gt;
Например, если мы работаем с элементами $x$ и $y$, то мы можем сначала взять блокировку на $x$, потом поработать с $x$, потом взять блокировку на $y$, поработать с ним, а потом отпустить все блокировки.&lt;br /&gt;
&lt;br /&gt;
[[Файл:distributed-2pl.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Если все транзакции устроены таким образом, то гарантируется сериализуемость транзакции.&lt;br /&gt;
&lt;br /&gt;
== Применение ==&lt;br /&gt;
Так можно брать не все блокировки, а только нужные.&lt;br /&gt;
Это особенно удобно в СУБД, когда движок заранее не знает, какие блокировки потребуются: он может просто набирать блокировки, как появляются запросы, а в конце, при применении транзакции, их разом отпустить.&lt;br /&gt;
&lt;br /&gt;
Из-за этого могут возникнуть проблемы с взаимными блокировками (потому что порядок взятия блокировок может отличаться в разных транзакциях), поэтому:&lt;br /&gt;
* [[Определение взаимной блокировки|Детектор взаимных блокировок]] всё равно нужен. Если нашли — то отменяем одну из транзакций и снимаем все её блокировки. Есть разные стратегии выбора, какую транзакцию отменять. Можно самую новую (тогда мы будем дожидаться старой), можно самую долго работающую (тогда у коротких запросов приоритет), можно ещё как-то.&lt;br /&gt;
* В некоторых СУБД есть даже специальный SQL-синтаксис для deadlock avoidness, вроде &amp;lt;code&amp;gt;SELECT FOR UPDATE&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проблемы, конечно, в том, что если у нас большой запрос по всем строкам таблицы, то нам нужно всё заблокировать, но для этого есть [[Транзакции в распределённых системах#Согласованность и изоляция|MVCC]] или пониженные уровни изоляции.&lt;/div&gt;</summary>
		<author><name>139.45.249.101</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1%D0%BA%D0%B8%D0%BD%D0%B0&amp;diff=81134</id>
		<title>Алгоритм Скина</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1%D0%BA%D0%B8%D0%BD%D0%B0&amp;diff=81134"/>
				<updated>2021-07-02T16:09:16Z</updated>
		
		<summary type="html">&lt;p&gt;139.45.249.101: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория: Параллельное программирование]]&lt;br /&gt;
'''Алгоритм Скина'''&amp;lt;ref&amp;gt;https://doi.org/10.1109/TSE.1983.236608&amp;lt;/ref&amp;gt; для организации [[Общий порядок сообщений|общего порядка сообщений]].&lt;br /&gt;
Лучше, чем [[Алгоритм Лампорта]], потому что для multicast сообщений общается только с получателями, а не со всеми процессами системы.&lt;br /&gt;
&lt;br /&gt;
Используются [[Логические часы Лампорта|логические часы Лампорта]].&lt;br /&gt;
Ниже алгоритм расписан чуть подробнее, чем в Garg и на лекции, но вроде всё ещё верно.&lt;br /&gt;
&lt;br /&gt;
У каждого процесса есть очередь принятых необработанных multicast сообщений.&lt;br /&gt;
Каждое сообщение имеет временну́ю метку и флаг — финализирована ли метка.&lt;br /&gt;
&lt;br /&gt;
# Инициатор отправляет сообщение и своё время (''предварительное время сообщения'') всем получателям&lt;br /&gt;
# При приеме сообщения процесс запоминает сообщение со временем в очередь (как нефинализированное) и отправляет свое время инициатору&lt;br /&gt;
# Когда инициатору вернулись все подтверждения, он выбирает максимальное время из них и снова отправляет сообщение с финализированным временем&lt;br /&gt;
# Получатель может обработать сообщение, если оно помечено как финальное и имеет минимальное время среди всех известных получателю сообщений (и финальных, и нефинальных; иначе может получиться, что финализация сообщений произойдёт в разном порядке у разных получателей и нарушится общий порядок)&lt;br /&gt;
&lt;br /&gt;
Полный порядок задается финальными временными метками. Финальные метки нужны, чтобы как-то зависеть от времени получателей.&lt;br /&gt;
Доказательство на лекции и в Gaarg не приводилось.&lt;br /&gt;
&lt;br /&gt;
Итого $3(k-1)$ сообщений на каждый multicast на $k$ процессов (не обсуждалось на лекции, но вроде так).&lt;/div&gt;</summary>
		<author><name>139.45.249.101</name></author>	</entry>

	</feed>