Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

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



Все ОС, поддерживающие многозадачность или мультипроцессорную обработку, должны предоставлять потокам способ ожидания того, что другой поток что–либо сделает: например, освободит накопитель на магнитном диске или закончит запись в совместно используемый буфер памяти. ОС должна также дать потоку возможность сообщить другим потокам об окончании выполнения операции. Получив такое уведомление, ожидающий поток может продолжить выполнение.

Синхронизационные объекты и их состояния

1. процессы

2. потоки

3. задания

4. файлы

5. консольный ввод

6. уведомления об изменении файлов

7. события

8. ожидаемые таймеры

9. семафоры

10. мьютексы

Свободен Занят

Средства ожидания и сообщения реализованы в ядре Windows как часть объектной архитектуры.

Синхронизационные объекты (synchronization objects) – это объекты ядра, при помощи которых поток синхронизирует свое выполнение.

В любой момент времени синхронизационный объект находится в одном из двух состояний: свободен (signaled state) или занят.

Правила, по которым объект переходит в свободное или занятое состояние, зависят от типа этого объекта:

Объект-поток находится в состоянии «занят» все время существования, но устанавливается системой в состояние "свободен", когда его выполнение завершается. Аналогично, ядро устанавливает процесс в состояние "свободен", когда завершился его последний поток.

В противоположность этому, объект – таймер «срабатывает» через заданное время (по истечении этого времени ядро устанавливает объект – таймер в состояние "свободен").

События

События – самая примитивная разновидность объектов ядра.

События содержат счетчик числа пользователей (как и все объекты ядра) и две булевы переменные: одна сообщает тип данного объекта-события, другая – его состояние (свободен или занят).

События просто уведомляют об окончании какой-либо операции. Объекты-события бывают двух типов: со сбросом вручную (manual-reset events) и с автосбросом (auto-reset events). Разница в том, что первый вид события нужно применять если событие ждут несколько потоков. Только сброс вручную позволяет это сделать. Иначе первый же обработчик сбросит событие и другие потоки об этом не узнают.

Объекты-события обычно используют в том случае, когда какой-то поток выполняет инициализацию, а затем сигнализирует другому потоку, что тот может продолжить работу. Инициализирующий поток переводит объект "событие” в занятое состояние и приступает к своим операциям. Закончив, он сбрасывает событие в свободное состояние. Тогда другой поток, который ждал перехода события в свободное состояние, пробуждается и вновь становится планируемым.

Иллюстрация работы “события”

       
   

событие с ручным сбросом событие с автоматическим сбросом

Создание события

HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES psa,

BOOL fManualReset,

BOOL fInitialState,

LPCTSTR pszName);

HANDLE OpenEvent(

DWORD fdwAccess,

BOOL fInhent,

LPCTSTR pszName);

Объект ядра “событие" создается функцией CreateEvent.

Параметр fManualReset (булева переменная) сообщает системе, хотите Вы создать событие со сбросом вручную (TRUE) или с автосбросом (FALSE).

Параметр fInitialState определяет начальное состояние события – свободное (TRUE) или занятое (FALSE). После того как система создает объект событие, CreateEvent возвращает описатель события, специфичный для конкретного процесса.

Потоки из других процессов могут получить доступ к этому объекту:

наследованием описателя с применением функции DuplicateHandle;

вызовом OpenEvent cпередачей в параметре pszName имени, совпадающего с указанным в аналогичном параметре функции CreateEvent.

Управление событием

Перевод события в свободное состояние:

BOOL SetEvent (HANDLE hEvenеt);

Перевод события в занятое состояние:

BOOL ResetEvent (HANDLE hEvent);

Освобождение события и перевод его обратно в занятое состояние:

BOOL PulseEvent (HANDLE hEvent);

Особенности PulseEvent

Функция PulseEvent устанавливает событие и тут же переводит его обратно в сброшенное состояние.

Ее вызов равнозначен последовательному вызову SetEvent и ResetEvent. Если PulseEvent вызывается для события со сбросом вручную, то все потоки, ожидающие этот объект, получают управление.

При вызове PulseEvent для события с автосбросом пробуждается только один из ждущих потоков. А если ни один из потоков не ждет объект-событие, вызов функции не дает никакого эффекта.

Семафоры

Дийкстра (Dijkstra) предложил использовать переменные, которые могут принимать целые неотрицательные значения. Такие переменные, используемые для синхронизации вычислительных процессов, получили название семафоров.

Семафор - неотрицательная целая переменная S >= 0, которая может изменяться и проверяться только посредством двух примитивов:

V(S): переменная S увеличивается на 1 единым неделимым действием. К переменной S нет доступа другим потокам во время выполнения этой операции.

P(S): уменьшение S на 1, если это возможно. Если S=0 и невозможно уменьшить S, оставаясь в области целых неотрицательных значений, то в этом случае поток, вызывающий операцию Р, ждет, пока это уменьшение станет возможным. Успешная проверка и уменьшение также являются неделимой операцией.

Иллюстрация работы семафора

Данный пример демонстрирует использование семафора для ограничения доступа потоков к объекту синхронизации на основании их количества.

Создание семафора

HANDLE CreateSemaphore(

LPSECURITY_ATTRIBUTE psa,

LONG lInitialCount,

LONG lMaximumCount,

LPCTRTR pszName);

HANDLE OpenSemaphore(

DWORD fdwAccess,

BOOL bInheritHandle,

LPCTSTR pszName);

Параметр lMaximumCount сообщает системе максимальное состояние семафора.

Управление семафором

Поток получает доступ к ресурсу, вызывая одну из Wait -функций и передавая ей описатель семафора, который охраняет этот ресурс Wait- функция проверяет у семафора счетчик текущего числа ресурсов если его значение больше 0 (семафор свободен), уменьшает значение этого счетчика на 1, и вызывающий поток остается планируемым.

BOOL ReleaseSemaphore(

HANDLE hSem,

LONG lReleaseCount,

PLONG plPreviousCount);

Если Wait- функция определяет, что счетчик текущего числа ресурсов равен 0 (семафор занят), система переводит вызывающий поток в состояние ожидания Когда другой поток увеличит значение этого счетчика, система вспомнит о ждущем потоке и снова начнет выделять ему процессорное время (а он, захватив ресурс, уменьшит значение счетчика на 1).

Поток увеличивает значение счетчика текущего числа ресурсов, вызывая функцию ReleaseSemaphore.

Она просто складывает величину lReleaseCount со значением счетчика текущего числа ресурсов. Обычно в параметре lReleaseCount передают 1.

Функция возвращает исходное значение счетчика ресурсов в *plPreviousCount.





Дата публикования: 2014-11-19; Прочитано: 407 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.009 с)...