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

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

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

Классы синхронизации в .NET Framework

Interlocked

Класс Interlocked предоставляет атомарные операции для переменных, общедоступных нескольким потокам. К примеру, операции инкремента (i++) и декремента (i--) которые не являются безопасными при многопоточной обработке. Такие операции могут прерываться планировщиком потоков. Класс Interlocked позволяет выполнять операции инкремента, декремента, обмена и считывания значений, в безопасной к потокам манере.

Применение класса Interlocked является гораздо более быстрым подходом по сравнению с остальными приемами по обеспечению синхронизации. Однако пользоваться им можно для устранения только простых последствий синхронизации.

Таблица 5.1. Методы класса Interlocked
Имя Описание
CompareExchange() Безопасно проверяет два значения на эквивалентность. Если они эквивалентны, изменяет одно из значений на третье
Decrement() Безопасно уменьшает значение на 1
Exchange() Безопасно меняет два значения местами
Increment() Безопасно увеличивает значение на 1

Можно так же использовать оператор lock для блокирования доступа к переменной при установке для нее нового значения, взамен метода Increment():

lock(x)
{
	x++;
} 

Но можно воспользоваться классом Interlocked. Метод Increment() не только изменяет значение входного параметра, но также возвращает полученное новое значение:

public void Proc()
{
   int x = Interlocked.Increment(ref intVal);
}

В дополнение, методы Increment() и Decrement() позволяют автоматически присваивать значения переменным. В примере переменной x присваивается значение 2:

public int x;
public void Proc ()
{
    Interlocked.Exchange(ref x, 2);
}

Класс Monitor

Класс Monitor предназначен для того, чтобы контролировать доступ к объектам, предоставляя блокировку объекта одному потоку. Блокировки объектов предоставляют возможность ограничения доступа к части кода, обычно называемой критической секцией. Пока поток владеет блокировкой для объекта, никакой другой поток не может ею завладеть.

В классе Monitor определено несколько методов синхронизации. Например, чтобы получить возможность блокировки для некоторого объекта, вызывается метод Enter(), а чтобы снять блокировку - метод Exit(). Эти методы имеют следующий формат:

public static void Enter(object syncOb) 
public static void Exit(object syncOb)

где syncOb - синхронизируемый объект. Если при вызове метода Enter() заданный объект недоступен, вызывающий поток будет ожидать до тех пор, пока объект не станет доступным.

Использование оператора lock эквивалентно вызову метода Enter() с последующим вызовом метода Exit() класса Monitor. Класс Monitor обладает одним важным преимуществом по сравнению с оператором lock: он позволяет добавлять значение тайм-аута для ожидания получения блокировки. Таким образом, вместо того, чтобы ожидать блокировку до бесконечности, можно вызвать метод TryEnter() и передать в нем значение тайм-аута, указывающее, сколько максимум времени должно ожидаться получение блокировки. Один из форматов его использования метода TryEnter():

public static bool TryEnter(object syncOb)

Метод возвращает значение true, если вызывающий поток получает блокировку для объекта syncOb, и значение false в противном случае. Если заданный объект недоступен, вызывающий поток будет ожидать до тех пор, пока он не станет доступным.

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

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

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

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