67 lines
3 KiB
HTML
67 lines
3 KiB
HTML
<html>
|
||
|
||
<head>
|
||
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
|
||
<param name="Keyword" value="critical">
|
||
</object>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
|
||
<title></title>
|
||
<link rel="StyleSheet" href="../../default.css">
|
||
</head>
|
||
|
||
<body>
|
||
<H1>Синхронизация и директива critical </H1>
|
||
<p>Директива <code>critical</code> исключает параллельное выполнение следующего за ней
|
||
оператора.</p>
|
||
<blockquote>
|
||
<p><code><font color="#666666">{$omp critical имя}<br>
|
||
</font><i>оператор</i>;</code></p>
|
||
</blockquote>
|
||
<p>Этот оператор образует критическую секцию – участок кода, который не может
|
||
выполняться одновременно несколькими потоками.</p>
|
||
<p>Только критические секции с одинаковыми именами не могут выполняться
|
||
одновременно. Если один поток уже выполняет критическую секцию, а второй
|
||
пытается войти в секцию с таким же именем, он будет заблокирован до тех пор,
|
||
пока первый поток не выйдет за пределы критической секции.</p>
|
||
<p>Критические секции можно использовать при обращении к общим переменным, чтобы
|
||
избежать потерь данных.</p>
|
||
<blockquote>
|
||
<p><code><b>var</b> a:integer:=0;<br>
|
||
<font color="#666666">{$omp parallel for}<br>
|
||
</font><b>for</b> <b>var</b> i:integer:=1 <b>to</b> 100 <b>do</b><br>
|
||
{$omp critical}<br>
|
||
a:=a+1;</code></p>
|
||
</blockquote>
|
||
<p>Здесь критическую секцию можно использовать вместо редукции. Весь оператор
|
||
<code>a:=a+1</code> выполнится одним потоком и только потом – другим. Однако использование
|
||
критических секций обычно снижает эффективность за счет последовательного
|
||
выполнения этих участков. В этом примере все тело цикла является критической
|
||
секцией, поэтому весь цикл будет выполнен последовательно.</p>
|
||
<p>Но не во всех случаях использование критических секций помогает обеспечить
|
||
корректную работу параллельных конструкций.</p>
|
||
<blockquote>
|
||
<p><code><b>var</b> a:integer := 0;<br>
|
||
<font color="#666666">{$omp parallel sections}<br>
|
||
</font><b>begin</b><br>
|
||
<font color="#666666"> {$omp critical}<br>
|
||
</font> a:=1;<br>
|
||
<font color="#666666"> {$omp critical}<br>
|
||
</font> a:=a+1;<br>
|
||
<b>end</b>;</code></p>
|
||
</blockquote>
|
||
<p>Значение переменной a зависит от того, в каком порядке выполнятся секции.
|
||
Если первая секция выполнится раньше, значение a будет равно двум, иначе –
|
||
единице.</p>
|
||
<p>При использовании критических секций возможно возникновение взаимоблокировок.
|
||
Например, первый поток выполняет код, содержащий критическую секцию A, внутри
|
||
которой есть критическая секция B. Второй поток выполняет код, содержащий
|
||
критическую секцию B, внутри которой есть критическая секция A. Возможен такой
|
||
порядок выполнения: первый поток входит в секцию А и не успевает войти в секцию
|
||
В. Второй поток входит в секцию В и не может войти в секцию А, так как эта
|
||
секция уже выполняется другим потоком. Первый поток не может продолжить
|
||
выполнение, так как секция В уже выполняется другим потоком. Оба потока
|
||
оказываются заблокированными.</p>
|
||
</body>
|
||
|
||
</html>
|