Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OC - Лекция 4 / OC - Лекция 4 (C#).ppt
Скачиваний:
27
Добавлен:
21.05.2015
Размер:
221.18 Кб
Скачать

Класс ThreadState

определяет набор всех возможных состояний выполнения для потока

 

 

 

 

Поток создается в среде CLR

Unstarted

 

 

Поток вызывает метод Start

Running

Поток начинает выполнение

Running

Поток вызывает метод Sleep

WaitSleepJoin

Поток вызывает метод Wait для другого объекта

WaitSleepJoin

Поток вызывает метод Join для другого потока

WaitSleepJoin

Другой поток вызывает метод Interrupt

Running

Другой поток вызывает метод Suspend

SuspendRequested

Поток отвечает на запрос метода Suspend

Suspended

Другой поток вызывает метод Resume

Running

Другой поток вызывает метод Abort

AbortRequested

Поток отвечает на запрос метода Abort

Stopped

Поток завершен

Stopped

 

 

 

 

Диаграмма состояний потока

Синхронизация

Процесс координации потоков называется синхронизацией. В основе синхронизации лежит понятие блокировки, т.е.

управление доступом к некоторому блоку кода в объекте.

Синхронизация в С# поддерживается ключевым словом lock. Формат использования инструкции lock таков:

lock(object) { // Инструкции, подлежащие синхронизации.

}

Здесь параметр object - ссылка на синхронизируемый объект.

Если нужно синхронизировать только один элемент, фигурные

скобки можно опустить.

Инструкция lock должна использоваться только для объектов, определенных как private или internal, иначе внешние к данной

программе потоки смогут получить блокировку и не снимать ее.

Пример ThreadSincLock, AlterLoc

Чтобы заблокировать static-метод, достаточно использовать

инструкцию lock в следующем формате: lock(typeof(class) ) { // Блокируемый код}

Здесь class представляет собой имя класса, в котором

содержится

static-метод, подлежащий блокировке.

Класс Monitor и инструкция lock

Ключевое слово lock — это сокращенный вариант использования средств синхронизации, определенных в классе Monitor, принадлежащем пространству имен System.Threading.

В классе Monitor определено несколько методов синхронизации.

public static void Enter(object syncOb)

для получения возможности

 

блокировки для некоторого объекта

public static void Exit(object syncOb) public static bool TryEnter(object syncOb)

для снятия блокировки

возвращает значение true, если вызывающий поток получает блокировку для объекта syncOb, и

значение false в противном случае.

public static bool Wait(object waitOb)

public static bool Wait(object waitOb, int milliseconds)

public static void Pulse(object waitOb)

выполнение потока временно блокируется

ожидание до уведомления или до истечения периода времени, заданного

в миллисекундах

возобновление выполнения потока, стоящего первым в очереди потоков,

пребывающих в режиме ожидания

public static void PulseAll(object waitOb) возобновление всех ожидающих потоков

Класс Semaphore используется для управления доступом к пулу ресурсов

public sealed class Semaphore : WaitHandle

Метод public virtual bool WaitOne() блокирует текущий поток

до получения сигнала объектом WaitHandle. Возвращает значение true, когда текущий экземпляр получает сигнал. Если текущий экземпляр не получает сигнал, метод WaitOne() не

возвращает значения.

Метод public int Release() освобождает семафор. Возвращает значение семафора перед вызовом Release().

Счетчик на семафоре уменьшается на единицу каждый раз,

когда

в семафор входит поток, и увеличивается на единицу, когда поток освобождает семафор. Когда счетчик равен нулю,

последующие запросы блокируются, пока другие потоки не

освободят семафор. Когда семафор освобожден всеми потоками, счетчик имеет максимальное значение, заданное при создании

семафора. Release() для семафора с максимальным значением

Семафоры бывают двух типов:

локальные семафоры именованные системные.

При создании объекта Semaphore с помощью конструктора, позволяющего передавать параметр с именем семафора, объект связывается с имеющим данное имя семафором операционной системы. Именованные системные семафоры доступны в пределах всей операционной системы и могут быть использованы для синхронизации действий процессов. Можно создать несколько объектов Semaphore, представляющих один и тот же системный именованный семафор, и использовать метод OpenExisting для открытия существующего именованного системного семафора.

Локальный семафор существует только внутри одного процесса. Он может использоваться любым потоком в процессе, имеющим ссылку на локальный объект Semaphore. Каждый объект Semaphore является отдельным локальным семафором.

Пример ThreadSem

public sealed class Mutex : WaitHandle

примитив, который предоставляет эксклюзивный доступ к общему

ресурсу только одному потоку синхронизации.

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

Для запроса на владение мьютексом используется метод public virtual bool WaitOne(int millisecondsTimeout)

millisecondsTimeout - время ожидания в миллисекундах или Timeout.Infinite (-1) в случае неограниченного времени ожидания. Возвращает true при получении сигнала текущим экземпляром; в противном случае – false.

Поток должен вызвать метод

public void ReleaseMutex() ,

чтобы освободить мьютекс один раз.

Класс Mutex выполняет идентификацию потоков, т.е. мьютекс может освобождаться только потоком, получившим его. Класс Semaphore не обеспечивает потоковой идентификации. Если поток завершается, владея мьютексом, то мьютекс

называется брошенным. Состояние мьютекса задается сигнальным, и мьютекс переходит во владение следующему ожидающему потоку.

Мьютексы бывают двух типов:

Локальные мьютексы (без имени). Существуют только внутри одного процесса. Может использоваться любым потоком в процессе, который содержит ссылку на объект Mutex, представляющий мьютекс. Каждый неименованный объект Mutex представляет отдельный локальный мьютекс.

Именованные системные доступны в пределах всей операционной системы и могут быть использованы для синхронизации действий процессов. Можно создать объект Mutex, представляющий именованный системный мьютекс, используя конструктор с поддержкой имен. Объект операционной системы может быть создан в то же время, или существовать до создания объекта Mutex. Можно создать несколько объектов Mutex, представляющих один и тот же именованный системный мьютекс, и использовать метод OpenExisting для открытия существующего именованного системного мьютекса.

Пример ThreadMutex