Добавить в цитаты Настройки чтения

Страница 412 из 502

<b>  // Точка входа в поток,</b>

<b>  void Run() {</b>

<b>    Console.WriteLine(Thrd.Name + &quot; ожидает мьютекс.&quot;);</b>

<b>    // Получить мьютекс.</b>

<b>    SharedRes.Mtx.WaitOne();</b>

<b>    Console.WriteLine(Thrd.Name + &quot; получает мьютекс.&quot;);</b>

<b>    do {</b>

<b>      Thread.Sleep(500) ;</b>

<b>      SharedRes.Count--;</b>

<b>      Console.WriteLine(&quot;В потоке &quot; + Thrd.Name +</b>

<b>             &quot;, SharedRes.Count = &quot; + SharedRes.Count);</b>

<b>      num-- ;</b>

<b>    } while(num &gt; 0);</b>

<b>    Console.WriteLine(Thrd.Name + &quot; освобождает мьютекс.&quot;);</b>

<b>    // Освободить мьютекс.</b>

<b>    SharedRes.Mtx.ReleaseMutex();</b>

<b>  }</b>

<b>}</b>

<b>class MutexDemo {</b>

<b>  static void Main() {</b>

<b>    // Сконструировать два потока.</b>

<b>    IncThread mt1 = new IncThread(&quot;Инкрементирующий Поток&quot;, 5);</b>

<b>    Thread.Sleep(1); // разрешить инкрементирующему потоку начаться</b>

<b>    DecThread mt2 = new DecThread(&quot;Декрементирующий Поток&quot;, 5);</b>

<b>    mt1.Thrd.Join();</b>

<b>    mt2.Thrd.Join();</b>

<b>  }</b>

<b>}</b>

Эта программа дает следующий результат.

<b>Инкрементирующий Поток ожидает мьютекс.</b>

<b>Инкрементирующий Поток получает мьютекс.</b>

<b>Декрементирующий Поток ожидает мьютекс.</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 1</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 2</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 3</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 4</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 5</b>

<b>Инкрементирующий Поток освобождает мьютекс.</b>

<b>Декрементирующий Поток получает мьютекс.</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 4</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 3</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 2</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 1</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 0</b>

<b>Декрементирующий Поток освобождает мьютекс.</b>

Как следует из приведенного выше результата, доступ к общему ресурсу (переменной SharedRes.Count) синхронизирован, и поэтому значение данной переменной может быть одновременно изменено только в одном потоке.

Для того чтобы убедиться в том, что мьютекс необходим для получения приведенного выше результата, попробуйте закомментировать вызовы методов WaitOne() и ReleaseMutex() в исходном коде рассматриваемой здесь программы. При ее последующем выполнении вы получите следующий результат, хотя у вас он может оказаться несколько иным.

<b>Инкрементирующий Поток ожидает мьютекс.</b>

<b>Инкрементирующий Поток получает мьютекс.</b>

<b>Декрементирующий Поток ожидает мьютекс.</b>

<b>Декрементирующий Поток получает мьютекс.</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 1</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 0</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 1</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 0</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 1</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 0</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 1</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 0</b>

<b>В потоке Инкрементирующий Поток, SharedRes.Count = 1</b>

<b>Инкрементирующий Поток освобождает мьютекс.</b>

<b>В потоке Декрементирующий Поток, SharedRes.Count = 0</b>

<b>Декрементирующий Поток освобождает мьютекс.</b>

Как следует из приведенного выше результата, без мьютекса инкрементирование и декрементирование переменной SharedRes.Count происходит, скорее, беспорядочно, чем последовательно.

Мьютекс, созданный в предыдущем примере, известен только тому процессу, который его породил. Но мьютекс можно создать и таким образом, чтобы он был известен где-нибудь еще. Для этого он должен быть именованным. Ниже приведены формы конструктора, предназначенные для создания такого мьютекса.