<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.linuxformat.ru/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF163%3AErlang%3A_%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D1%83%D0%B5%D0%BC_%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8E</id>
		<title>LXF163:Erlang: Программируем синхронизацию - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF163%3AErlang%3A_%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D1%83%D0%B5%D0%BC_%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8E"/>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF163:Erlang:_%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D1%83%D0%B5%D0%BC_%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8E&amp;action=history"/>
		<updated>2026-05-13T10:51:50Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.19.20+dfsg-0+deb7u3</generator>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/index.php?title=LXF163:Erlang:_%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D1%83%D0%B5%D0%BC_%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8E&amp;diff=18856&amp;oldid=prev</id>
		<title>Olkol: /* Erlang: Программируем синхронизацию */</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF163:Erlang:_%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D1%83%D0%B5%D0%BC_%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8E&amp;diff=18856&amp;oldid=prev"/>
				<updated>2018-10-21T00:03:28Z</updated>
		
		<summary type="html">&lt;p&gt;‎&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Erlang: Программируем синхронизацию&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
			&lt;tr valign='top'&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 00:03, 21 октября 2018&lt;/td&gt;
			&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 33:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 33:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;В этом при­ме­ре мы по­ка­за­ли про­бле­му, из­вест­ную как со­стя­зание (гонка) за ре­сур­сы. Дру­гая из­вест­ная про­бле­ма, свя­зан­ная с од­но­вре­мен­ным из­менением дан­ных – по­вре­ж­дение дан­ных. Обыч­но дан­ные по­вре­ж­да­ют­ся, когда несколь­ко за­дач од­но­вре­мен­но об­нов­ля­ют слож­ные струк­ту­ры дан­ных, доступ к ко­то­рым не ато­ма­рен на уровне про­цес­со­ра. На­при­мер, на плат­фор­ме x86 та­кой струк­ту­рой дан­ных бу­дут 64-бит­ные це­лые чис­ла. По­сле та­ко­го об­нов­ления в по­доб­ной струк­ту­ре мо­гут со­дер­жать­ся дан­ные всех про­цес­сов, про­из­во­див­ших об­нов­ление, и, со­от­вет­ст­вен­но, са­ма струк­ту­ра со­дер­жит дан­ные, ко­то­рые в ней не поя­ви­лись бы, ес­ли бы все про­цес­сы об­нов­ля­ли ее по­сле­до­ва­тель­но. Возника­ет вполне ло­гич­ный во­прос: что на­до де­лать, что­бы по­доб­ных си­туа­ций не возника­ло? От­вет вполне оче­ви­ден: ес­ли несколь­ко про­цес­сов од­но­вре­мен­но об­ра­ща­ют­ся к неко­то­рым дан­ным, при­чем неко­то­рые из этих про­цес­сов из­ме­ня­ют об­щие дан­ные, то для досту­па к этим дан­ным необ­хо­ди­мо ис­поль­зо­вать сред­ст­ва син­хрониза­ции.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;В этом при­ме­ре мы по­ка­за­ли про­бле­му, из­вест­ную как со­стя­зание (гонка) за ре­сур­сы. Дру­гая из­вест­ная про­бле­ма, свя­зан­ная с од­но­вре­мен­ным из­менением дан­ных – по­вре­ж­дение дан­ных. Обыч­но дан­ные по­вре­ж­да­ют­ся, когда несколь­ко за­дач од­но­вре­мен­но об­нов­ля­ют слож­ные струк­ту­ры дан­ных, доступ к ко­то­рым не ато­ма­рен на уровне про­цес­со­ра. На­при­мер, на плат­фор­ме x86 та­кой струк­ту­рой дан­ных бу­дут 64-бит­ные це­лые чис­ла. По­сле та­ко­го об­нов­ления в по­доб­ной струк­ту­ре мо­гут со­дер­жать­ся дан­ные всех про­цес­сов, про­из­во­див­ших об­нов­ление, и, со­от­вет­ст­вен­но, са­ма струк­ту­ра со­дер­жит дан­ные, ко­то­рые в ней не поя­ви­лись бы, ес­ли бы все про­цес­сы об­нов­ля­ли ее по­сле­до­ва­тель­но. Возника­ет вполне ло­гич­ный во­прос: что на­до де­лать, что­бы по­доб­ных си­туа­ций не возника­ло? От­вет вполне оче­ви­ден: ес­ли несколь­ко про­цес­сов од­но­вре­мен­но об­ра­ща­ют­ся к неко­то­рым дан­ным, при­чем неко­то­рые из этих про­цес­сов из­ме­ня­ют об­щие дан­ные, то для досту­па к этим дан­ным необ­хо­ди­мо ис­поль­зо­вать сред­ст­ва син­хрониза­ции.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;{{Врезка|right|Заголовок= Ре­ен­те­ра­бель­ность бло­ки­ро­вок|Ширина=50%|Содержание= Ре­ен­те­ра­бель­ность – это воз­мож­ность по­втор­но­го ис­поль­зо­вания ка­ко­го-ли­бо объ­ек­та или вы­зо­ва функ­ции в мо­мент, когда дан­ный объ­ект ис­поль­зу­ет­ся или функ­ция вы­зва­на. В слу­чае объ­ек­тов бло­ки­ров­ки это оз­на­ча­ет, мо­жет ли од­на и та же сто­ро­на «за­хва­тить» объ­ект бло­ки­ров­ки несколь­ко раз. Ес­ли да, то та­кой объ­ект бло­ки­ров­ки яв­ля­ет­ся ре­ен­те­ра­бель­ным (при этом, ес­ли мы N раз «за­хва­ти­ли» объ­ект бло­ки­ров­ки, его необ­хо­ди­мо «осво­бо­дить» так­же N раз); ес­ли же нет – нере­ен­те­ра­бель­ным (при по­пыт­ках «за­хва­тить» та­кой объ­ект бло­ки­ров­ки несколь­ко раз мы в ито­ге по­лу­чим са­мо­бло­ки­ров­ку). Бло­ки­ров­ки, под­дер­жи­вае­мые мо­ду­лем global, яв­ля­ют­ся ре­ен­те­ра­бель­ны­ми. }} &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Сле­ду­ет ска­зать, что на мно­го­ядер­ных и мно­го­про­цес­сор­ных ма­ши­нах воз­мож­на гон­ка за ре­сур­сы, свя­зан­ная с тем, что раз­ные яд­ра (или про­цес­со­ры) в сво­ей кэш-па­мя­ти со­дер­жат раз­ные зна­чения од­ной и той же пе­ре­мен­ной. Это спра­вед­ли­во, да­же ес­ли доступ к та­кой пе­ре­мен­ной ато­ма­рен на уровне про­цес­со­ра, как, на­при­мер, для 32-бит­ных це­лых чи­сел на плат­фор­ме x86. Сле­ду­ет учитывать по­доб­ные си­туа­ции и при­ме­нять со­от­вет­ст­вую­щие сред­ст­ва син­хрониза­ции, что­бы из­бе­жать их.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Сле­ду­ет ска­зать, что на мно­го­ядер­ных и мно­го­про­цес­сор­ных ма­ши­нах воз­мож­на гон­ка за ре­сур­сы, свя­зан­ная с тем, что раз­ные яд­ра (или про­цес­со­ры) в сво­ей кэш-па­мя­ти со­дер­жат раз­ные зна­чения од­ной и той же пе­ре­мен­ной. Это спра­вед­ли­во, да­же ес­ли доступ к та­кой пе­ре­мен­ной ато­ма­рен на уровне про­цес­со­ра, как, на­при­мер, для 32-бит­ных це­лых чи­сел на плат­фор­ме x86. Сле­ду­ет учитывать по­доб­ные си­туа­ции и при­ме­нять со­от­вет­ст­вую­щие сред­ст­ва син­хрониза­ции, что­бы из­бе­жать их.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 49:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 50:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Со сред­ст­ва­ми син­хрониза­ции с бло­ки­ров­ка­ми свя­за­на так­же та­кая боль­шая про­бле­ма, как вза­им­ные бло­ки­ров­ки за­дач. В про­стей­шем слу­чае вза­им­ные бло­ки­ров­ки за­дач по­лу­ча­ют­ся сле­дую­щим об­ра­зом. Пусть у нас есть два ре­сур­са – A и B, доступ к ко­то­рым за­щи­ща­ет­ся при по­мо­щи средств син­хрониза­ции с бло­ки­ров­ка­ми. Пред­по­ло­жим, что у нас есть две за­да­чи, ко­то­рые хо­тят безо­пас­но ра­бо­тать как с ре­сур­сом A, так и с ре­сур­сом B, при этом пер­вая за­да­ча сна­ча­ла пы­та­ет­ся «за­хва­тить» бло­ки­ров­ку, свя­зан­ную с ре­сур­сом A, а по­том с ре­сур­сом B, а вто­рая за­да­ча – на­обо­рот. При од­но­вре­мен­ном вы­полнении этих за­дач воз­мож­на та­кая си­туа­ция, когда пер­вая за­да­ча «за­хва­ти­ла» бло­ки­ров­ку, свя­зан­ную с ре­сур­сом A, и ожи­да­ет бло­ки­ров­ку, свя­зан­ную с ре­сур­сом B, тогда как вто­рая за­да­ча «за­хва­ти­ла» бло­ки­ров­ку, свя­зан­ную с ре­сур­сом B, и ожи­да­ет бло­ки­ров­ку, свя­зан­ную с ре­сур­сом A. Такое ожи­дание бу­дет веч­ным. Как мы го­во­ри­ли вы­ше, сред­ст­ва син­хрониза­ции – это сред­ст­ва взаи­мо­дей­ст­вия ме­ж­ду про­цес­са­ми, и ес­ли раз­ные за­да­чи «за­хва­ты­ва­ют» одни и те же бло­ки­ров­ки в раз­ном по­ряд­ке, это оз­на­ча­ет, что ка­кие-то из за­дач на­ру­ша­ют про­то­кол взаи­мо­дей­ст­вия ме­ж­ду за­да­ча­ми.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Со сред­ст­ва­ми син­хрониза­ции с бло­ки­ров­ка­ми свя­за­на так­же та­кая боль­шая про­бле­ма, как вза­им­ные бло­ки­ров­ки за­дач. В про­стей­шем слу­чае вза­им­ные бло­ки­ров­ки за­дач по­лу­ча­ют­ся сле­дую­щим об­ра­зом. Пусть у нас есть два ре­сур­са – A и B, доступ к ко­то­рым за­щи­ща­ет­ся при по­мо­щи средств син­хрониза­ции с бло­ки­ров­ка­ми. Пред­по­ло­жим, что у нас есть две за­да­чи, ко­то­рые хо­тят безо­пас­но ра­бо­тать как с ре­сур­сом A, так и с ре­сур­сом B, при этом пер­вая за­да­ча сна­ча­ла пы­та­ет­ся «за­хва­тить» бло­ки­ров­ку, свя­зан­ную с ре­сур­сом A, а по­том с ре­сур­сом B, а вто­рая за­да­ча – на­обо­рот. При од­но­вре­мен­ном вы­полнении этих за­дач воз­мож­на та­кая си­туа­ция, когда пер­вая за­да­ча «за­хва­ти­ла» бло­ки­ров­ку, свя­зан­ную с ре­сур­сом A, и ожи­да­ет бло­ки­ров­ку, свя­зан­ную с ре­сур­сом B, тогда как вто­рая за­да­ча «за­хва­ти­ла» бло­ки­ров­ку, свя­зан­ную с ре­сур­сом B, и ожи­да­ет бло­ки­ров­ку, свя­зан­ную с ре­сур­сом A. Такое ожи­дание бу­дет веч­ным. Как мы го­во­ри­ли вы­ше, сред­ст­ва син­хрониза­ции – это сред­ст­ва взаи­мо­дей­ст­вия ме­ж­ду про­цес­са­ми, и ес­ли раз­ные за­да­чи «за­хва­ты­ва­ют» одни и те же бло­ки­ров­ки в раз­ном по­ряд­ке, это оз­на­ча­ет, что ка­кие-то из за­дач на­ру­ша­ют про­то­кол взаи­мо­дей­ст­вия ме­ж­ду за­да­ча­ми.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Врезка|left|Заголовок= Бло­ки­ров­ки на пе­ре­кры­ваю­щих­ся под­мно­же­ст­вах уз­лов|Ширина=60%|Содержание=&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Функ­ции global:set_lock/1,2,3 и global:del_lock/1,2 по­зво­ля­ют «за­хва­ты­вать» и «осво­бо­ж­дать» бло­ки­ров­ки, за­дан­ные иден­ти­фи­ка­то­ром на мно­же­ст­ве уз­лов, оп­ре­де­ляе­мых поль­зо­ва­те­лем. Иден­ти­фи­ка­тор бло­ки­ров­ки – это па­ра, со­стоя­щая из иден­ти­фи­ка­то­ра ре­сур­са и иден­ти­фи­ка­то­ра сто­ро­ны, за­пра­ши­ваю­щей бло­ки­ров­ку (в ка­че­­ст­ве иден­ти­фи­ка­то­ров мо­гут вы­сту­пать лю­бые объ­ек­ты язы­ка Erlang). Мо­жет встать во­прос: а что бу­дет, ес­ли по­пы­тать­ся за­хва­тить один и тот же ре­сурс дву­мя раз­ны­ми сто­ро­на­ми на двух раз­ных, но пе­ре­кры­ваю­щих­ся под­мно­же­ст­вах уз­лов? На­при­мер, мы де­ла­ем вы­зов global:set_lock({res_id, side_id1}, [‘n1@stdstring’, ‘n2@stdstring’], 0), ко­то­рый воз­вра­ща­ет true. Что в та­ком слу­чае вернет вы­зов global:set_lock({res_id, side_id2}, [‘n2@stdstring’, ‘n3@stdstring’], 0)? Ес­ли бы мы за­пра­ши­ва­ли бло­ки­ров­ку {res_id, side_id2} толь­ко на уз­ле n3@stdstring, мы, оче­вид­но, ее «за­хва­ти­ли» бы (и вы­зов вер­нул бы true). Од­на­ко мы за­про­си­ли бло­ки­ров­ку на уз­лах ‘n2@stdstring’ и ‘n3@stdstring’; а з­на­чит, бло­ки­ров­ки толь­ко на уз­ле ‘n3@stdstring’ нам не доста­точ­но. Бло­ки­ров­ку {res_id, side_id2} на уз­ле ‘n2@stdstring’ «за­хва­тить» нельзя (она «за­хва­че­на» дру­гой сто­ро­ной). Со­от­вет­ст­вен­но, нельзя за­хва­тить эту бло­ки­ров­ку и на уз­лах ‘n2@stdstring’ и ‘n3@stdstring’. Тогда вто­рой вы­зов global:set_lock/3 вернет false.}} &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Что ка­са­ет­ся средств небло­ки­рую­щей син­хрониза­ции, то по­ми­мо силь­но­го усложнения раз­ра­ба­ты­вае­мых при­ло­жений, да­ле­ко не все мо­жет быть реа­ли­зо­ва­но толь­ко с их по­мо­щью. Так, на­при­мер, дву­связ­ный спи­сок не име­ет реа­ли­за­ции с ис­поль­зо­ванием средств небло­ки­рую­щей син­хрониза­ции. При ис­поль­зо­вании средств небло­ки­рую­щей син­хрониза­ции си­туа­ции вза­им­ной бло­ки­ров­ки за­дач возник­нуть не мо­жет. Но вполне мо­гут возник­нуть си­туа­ции за­цик­ли­вания за­да­чи и гон­ки за ре­сур­сы.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Что ка­са­ет­ся средств небло­ки­рую­щей син­хрониза­ции, то по­ми­мо силь­но­го усложнения раз­ра­ба­ты­вае­мых при­ло­жений, да­ле­ко не все мо­жет быть реа­ли­зо­ва­но толь­ко с их по­мо­щью. Так, на­при­мер, дву­связ­ный спи­сок не име­ет реа­ли­за­ции с ис­поль­зо­ванием средств небло­ки­рую­щей син­хрониза­ции. При ис­поль­зо­вании средств небло­ки­рую­щей син­хрониза­ции си­туа­ции вза­им­ной бло­ки­ров­ки за­дач возник­нуть не мо­жет. Но вполне мо­гут возник­нуть си­туа­ции за­цик­ли­вания за­да­чи и гон­ки за ре­сур­сы.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 119:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 121:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Вполне воз­мож­на си­туа­ция, что два раз­ных про­цес­са пы­та­ют­ся «за­хва­тить» бло­ки­ров­ку на ка­кой-то ре­сурс, ис­поль­зуя один и тот же иден­ти­фи­ка­тор за­пра­ши­ваю­щей сто­ро­ны. В этом слу­чае (ес­те­ст­вен­но, ес­ли бло­ки­ров­ка сво­бод­на) они оба ее «за­хва­тят»; од­на­ко и осво­бо­ж­дать эту бло­ки­ров­ку необ­хо­ди­мо им обо­им. Об­ласть дей­ст­вия этих бло­ки­ро­вок – все из­вест­ные уз­лы; од­на­ко об­ласть дей­ст­вия бло­ки­ров­ки мож­но из­менить, за­дав спи­сок уз­лов, для ко­то­рых дан­ная бло­ки­ров­ка бу­дет дей­ст­ви­тель­на. Ес­ли про­цесс, вла­дею­щей бло­ки­ров­кой, за­вер­шит­ся без ее осво­бо­ж­дения или же узел, на ко­то­ром вы­пол­ня­ет­ся та­кой про­цесс, за­вер­шит свою ра­бо­ту, то бло­ки­ров­ка ав­то­ма­ти­че­­ски осво­бо­дит­ся (ес­ли, конеч­но, ею никто боль­ше не вла­де­ет).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Вполне воз­мож­на си­туа­ция, что два раз­ных про­цес­са пы­та­ют­ся «за­хва­тить» бло­ки­ров­ку на ка­кой-то ре­сурс, ис­поль­зуя один и тот же иден­ти­фи­ка­тор за­пра­ши­ваю­щей сто­ро­ны. В этом слу­чае (ес­те­ст­вен­но, ес­ли бло­ки­ров­ка сво­бод­на) они оба ее «за­хва­тят»; од­на­ко и осво­бо­ж­дать эту бло­ки­ров­ку необ­хо­ди­мо им обо­им. Об­ласть дей­ст­вия этих бло­ки­ро­вок – все из­вест­ные уз­лы; од­на­ко об­ласть дей­ст­вия бло­ки­ров­ки мож­но из­менить, за­дав спи­сок уз­лов, для ко­то­рых дан­ная бло­ки­ров­ка бу­дет дей­ст­ви­тель­на. Ес­ли про­цесс, вла­дею­щей бло­ки­ров­кой, за­вер­шит­ся без ее осво­бо­ж­дения или же узел, на ко­то­ром вы­пол­ня­ет­ся та­кой про­цесс, за­вер­шит свою ра­бо­ту, то бло­ки­ров­ка ав­то­ма­ти­че­­ски осво­бо­дит­ся (ес­ли, конеч­но, ею никто боль­ше не вла­де­ет).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt; &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;По­сле это­го неболь­шо­го об­зо­ра взглянем на на­ших ге­ро­ев. Для «за­хва­та» бло­ки­ров­ки у нас есть сле­дую­щие три функ­ции: global:set_lock(Id), global:set_lock(Id, Nodes) и global:set_lock(Id, Nodes, Retries). Функ­ция global:set_lock/3 пы­та­ет­ся уста­но­вить бло­ки­ров­ку с иден­ти­фи­ка­то­ром Id, об­ласть дей­ст­вия ко­то­рой рас­про­стра­ня­ет­ся на уз­лы Nodes, с ко­ли­че­­ст­вом по­пы­ток уста­но­вить бло­ки­ров­ку Retries. В ка­че­­ст­ве зна­чения для чис­ла по­пы­ток уста­но­вить бло­ки­ров­ку мож­но пе­ре­дать лю­бое неот­ри­ца­тель­ное чис­ло или атом infinity. Функ­ция global:set_lock/3 бу­дет пы­тать­ся «за­хва­тить» бло­ки­ров­ку не бо­лее Retries раз, впа­дая на неко­то­рое вре­мя в сон в слу­чае неудач­ной по­пыт­ки (ес­ли зна­чением Retries яв­ля­ет­ся атом infinity, то функ­ция global:set_lock/3 бу­дет вы­пол­нять­ся, по­ка не «за­хва­тит» бло­ки­ров­ку). Эта функ­ция вернет атом true, ес­ли бло­ки­ров­ка бы­ла «за­хва­че­на», и false – в про­тив­ном слу­чае. Функ­ция global:set_lock/2 эк­ви­ва­лент­на функ­ции global:set_lock/3 со зна­чением Retries, рав­ным ато­му infinity. Функ­ция global:set_lock/1 эк­ви­ва­лент­на функ­ции global:set_lock/2, толь­ко бло­ки­ров­ка оп­ре­де­ля­ет­ся на всех уз­лах. Для осво­бо­ж­дения бло­ки­ров­ки слу­жат сле­дую­щие две функ­ции: global:del_lock(Id) и global:del_lock(Id, Nodes). Функ­ция global:del_lock/2 по­зво­ля­ет осво­бо­дить бло­ки­ров­ку, за­дан­ную иден­ти­фи­ка­то­ром Id, на уз­лах Nodes, а функ­ция global:del_lock/1 де­ла­ет то же са­мое на всех уз­лах.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;По­сле это­го неболь­шо­го об­зо­ра взглянем на на­ших ге­ро­ев. Для «за­хва­та» бло­ки­ров­ки у нас есть сле­дую­щие три функ­ции: global:set_lock(Id), global:set_lock(Id, Nodes) и global:set_lock(Id, Nodes, Retries). Функ­ция global:set_lock/3 пы­та­ет­ся уста­но­вить бло­ки­ров­ку с иден­ти­фи­ка­то­ром Id, об­ласть дей­ст­вия ко­то­рой рас­про­стра­ня­ет­ся на уз­лы Nodes, с ко­ли­че­­ст­вом по­пы­ток уста­но­вить бло­ки­ров­ку Retries. В ка­че­­ст­ве зна­чения для чис­ла по­пы­ток уста­но­вить бло­ки­ров­ку мож­но пе­ре­дать лю­бое неот­ри­ца­тель­ное чис­ло или атом infinity. Функ­ция global:set_lock/3 бу­дет пы­тать­ся «за­хва­тить» бло­ки­ров­ку не бо­лее Retries раз, впа­дая на неко­то­рое вре­мя в сон в слу­чае неудач­ной по­пыт­ки &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Врезка|right|Заголовок= Бло­ки­ров­ки: Уп­ро­щен­ный сце­на­рий|Ширина=60%|Содержание=Обыч­но ра­бо­та с бло­ки­ров­ка­ми ре­сур­сов вы­гля­дит так: мы «за­хва­ты­ва­ем» бло­ки­ров­ку, вы­пол­ня­ем некую функ­цию (или по­сле­до­ва­тель­ность дей­ст­вий, сво­ди­мую в некую функ­цию), по­сле че­го «осво­бо­ж­да­ем» бло­ки­ров­ку. Конеч­но, мы мо­жем не смочь «за­хва­тить» бло­ки­ров­ку: тогда дальней­ших дей­ст­вий не пред­ви­дит­ся. Что­бы уп­ро­стить этот сце­на­рий, в мо­ду­ле global оп­ре­де­ле­ны функ­ции global:trans/2,3,4. Функ­ция global:trans(Id, Fun, Nodes, Retries) пы­та­ет­ся за­хва­тить бло­ки­ров­ку с иден­ти­фи­ка­то­ром Id на уз­лах Nodes Retries раз. Ес­ли «за­хват» осу­ще­ст­в­лен, вы­пол­ня­ет­ся функ­ция Fun, бло­ки­ров­ка «осво­бо­ж­да­ет­ся» и воз­вра­ща­ет­ся ре­зуль­тат вы­полнения функ­ции Fun. Ес­ли «за­хва­тить» бло­ки­ров­ку не уда­лось, воз­вра­ща­ет­ся атом aborted. }}&lt;/ins&gt;(ес­ли зна­чением Retries яв­ля­ет­ся атом infinity, то функ­ция global:set_lock/3 бу­дет вы­пол­нять­ся, по­ка не «за­хва­тит» бло­ки­ров­ку). Эта функ­ция вернет атом true, ес­ли бло­ки­ров­ка бы­ла «за­хва­че­на», и false – в про­тив­ном слу­чае. Функ­ция global:set_lock/2 эк­ви­ва­лент­на функ­ции global:set_lock/3 со зна­чением Retries, рав­ным ато­му infinity. Функ­ция global:set_lock/1 эк­ви­ва­лент­на функ­ции global:set_lock/2, толь­ко бло­ки­ров­ка оп­ре­де­ля­ет­ся на всех уз­лах. Для осво­бо­ж­дения бло­ки­ров­ки слу­жат сле­дую­щие две функ­ции: global:del_lock(Id) и global:del_lock(Id, Nodes). Функ­ция global:del_lock/2 по­зво­ля­ет осво­бо­дить бло­ки­ров­ку, за­дан­ную иден­ти­фи­ка­то­ром Id, на уз­лах Nodes, а функ­ция global:del_lock/1 де­ла­ет то же са­мое на всех уз­лах.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Се­го­дня мы по­зна­ко­ми­лись по­бли­же с та­ким яв­лением, как син­хрониза­ция за­дач (и с ее реа­ли­за­ци­ей в язы­ке Erlang). Мы уви­де­ли, что ниче­го страш­но­го в син­хрониза­ции нет: доста­точ­но быть ак­ку­рат­ным и со­блю­дать при­ня­тые про­то­ко­лы взаи­мо­дей­ст­вия ме­ж­ду за­да­ча­ми. А в сле­дую­щем но­ме­ре мы начнем прак­ти­кум, по­свя­щен­ный соз­данию мно­го­за­дач­ных при­ло­жений. |&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Се­го­дня мы по­зна­ко­ми­лись по­бли­же с та­ким яв­лением, как син­хрониза­ция за­дач (и с ее реа­ли­за­ци­ей в язы­ке Erlang). Мы уви­де­ли, что ниче­го страш­но­го в син­хрониза­ции нет: доста­точ­но быть ак­ку­рат­ным и со­блю­дать при­ня­тые про­то­ко­лы взаи­мо­дей­ст­вия ме­ж­ду за­да­ча­ми. А в сле­дую­щем но­ме­ре мы начнем прак­ти­кум, по­свя­щен­ный соз­данию мно­го­за­дач­ных при­ло­жений. |&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Olkol</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/index.php?title=LXF163:Erlang:_%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D1%83%D0%B5%D0%BC_%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8E&amp;diff=18855&amp;oldid=prev</id>
		<title>Olkol: Новая страница: «Категория: Учебники   Категория: Программирование   Категория: Синхронизация    '''Erl…»</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF163:Erlang:_%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D1%83%D0%B5%D0%BC_%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8E&amp;diff=18855&amp;oldid=prev"/>
				<updated>2018-10-20T23:50:12Z</updated>
		
		<summary type="html">&lt;p&gt;Новая страница: «&lt;a href=&quot;/wiki/%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%A3%D1%87%D0%B5%D0%B1%D0%BD%D0%B8%D0%BA%D0%B8&quot; title=&quot;Категория:Учебники&quot;&gt;Категория: Учебники&lt;/a&gt;   &lt;a href=&quot;/wiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Категория:Программирование (страница не существует)&quot;&gt;Категория: Программирование&lt;/a&gt;   &lt;a href=&quot;/wiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%A1%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Категория:Синхронизация (страница не существует)&quot;&gt;Категория: Синхронизация&lt;/a&gt;    &amp;#039;&amp;#039;&amp;#039;Erl…»&lt;/p&gt;
&lt;a href=&quot;http://wiki.linuxformat.ru/wiki/index.php?title=LXF163:Erlang:_%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D1%83%D0%B5%D0%BC_%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8E&amp;amp;diff=18855&quot;&gt;Внесённые изменения&lt;/a&gt;</summary>
		<author><name>Olkol</name></author>	</entry>

	</feed>