Томский политехнический университет
Опубликован: 23.01.2013 | Доступ: свободный | Студентов: 1158 / 192 | Длительность: 12:09:00
Лекция 4:

Синхронизация потоков

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >

Класс Mutex

Когда двум или более потокам одновременно требуется доступ к общему ресурсу, системе необходим механизм синхронизации, чтобы обеспечить использование ресурса только одним потоком одновременно. Класс Mutex, определенный в пространстве имен System. Threading - это примитив, который предоставляет эксклюзивный доступ к общему ресурсу только одному потоку синхронизации. Если поток получает семафор, второй поток, желающий получить этот семафор, приостанавливается до тех пор, пока первый поток не освободит семафор. Термин Mutex происходит от фразы mutually exclusive (взаимно исключающий), и поскольку только один поток может получить блокировку монитора для данного объекта в любой момент времени, только один поток в любой момент времени может получить данный Mutex. Класс Mutex очень похож на класс Monitor тем, что тоже допускает наличие только одного владельца. Только один поток может получить блокировку и иметь доступ к защищаемым Mutex синхронизированным областям кода. У Mutex имеется несколько конструкторов. Ниже приведены три наиболее употребительных конструктора:

public Mutex()
public Mutex(bool initiallyOwned);
public Mutex(bool initiallyOwned, string name_mutex)

В первой форме конструктора создается Mutex, которым первоначально никто не владеет. А во второй и третей форме исходным состоянием Mutex завладевает вызывающий поток, если параметр initiallyOwned имеет логическое значение true, если false, то объектом Mutex никто не владеет.

Для того чтобы получить Mutex, используется метод WaitOne(). Метод WaitOne() ожидает до тех пор, пока не будет получен Mutex, для которого он был вызван. Следовательно, этот метод блокирует выполнение вызывающего потока до тех пор, пока не станет доступным указанный Mutex. Данный метод всегда возвращает логическое значение true. Форма объявления метода WaitOne():

Mutex mutex = new Mutex(false);
mutex.WaitOne();

Когда в коде не требуется использовать Mutex, он освобождается с помощью метода ReleaseMutex():

mutex.ReleaseMutex();

Ниже продемонстрирован код реализующий работу Mutex:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Mutext
{
    class Program
    {
        private static Mutex mut = new Mutex();
        private const int numIterations = 1;
        private const int numThreads = 3;
        private static void Main(string[] args)
        {
            // Создаем потоки, которые будут использовать защищенный ресурс
            for (int i = 0; i < numThreads; i++)
            {
                Thread myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format("Поток{0}", i + 1);
                myThread.Start();
            }
            // Главный поток завершил работу
        }
        private static void MyThreadProc()
        {
            for (int i = 0; i < numIterations; i++)
            {
                UseResource();
            }
        }
        //Синхронизируем данный метод
        private static void UseResource()
        {
            mut.WaitOne();
            Console.WriteLine("{0} зашел в защищенную зону",
                Thread.CurrentThread.Name);
            // Имитируем работу
            Thread.Sleep(500);
            Console.WriteLine("{0} покинул защищенную зону",
                Thread.CurrentThread.Name);
            // Release the Mutex.
        mut.ReleaseMutex();
        Console.ReadLine();
        }
  }}

Результат работы программы, с использованием Mutex, представлен на Рис. 5.5.

 Результат выполнения программы с использованием синхронизации Mutex

увеличить изображение
Рис. 5.5. Результат выполнения программы с использованием синхронизации Mutex

Если же закомментировать методы WaitOne() и ReleaseMutex() и запустить программу, то программа сгенерирует результат, представленный на Рис. 5.6.

 Результат выполнения программы без использования синхронизации Mutex

увеличить изображение
Рис. 5.6. Результат выполнения программы без использования синхронизации Mutex

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >
Владимир Каширин
Владимир Каширин

Вопрос по Курсу: "Параллельное программирование с использованием MS VisualStudia 2010".

При компиляции Самостоятельного задания (одновременная отрисовка прямоугольников, эллипсов и выдача в текст-бокс случайного числа) среда предупреждает: suspend - устаревшая команда; примените monitor, mutex и т.п.

Создаётся впечатление, что Задание создано в более поздней среде, чем VS 2010.