пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

Синхронизация потоков при помощи объектов ядра. Семафоры. Пример

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

Но что делать, если необходимо синхронизировать работу потока с событиями, возникающими в системе или другом процессе?

Для этого в ОС предусмотрен ряд механизмов. Их можно применить при синхронизации со следующими объектами ядра:

мьютексы,

семафоры,

события,

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

Эти четыре объекта предназначены собственно для синхронизации и не имеют другого назначения, в отличии от первых трех объектов.  

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

DWORD WaitForSingleObject(HANDLE hObject, DWORD dwMilliseconds);

С помощью данной функции поток сообщает системе, что будет ожидать освобождения объекта hObject в течении dwMilliseconds миллисекунд. Функция возвращает следующие значения:

WAIT_OBJECT_0 – Объект перешел в свободное состояние

WAIT_TIMEOUT – Истекло время ожидания

WAIT_FAILED – Ошибка

Если dwTimeOut равно 0, то функция просто вернет состояние объекта. Если dwTimeOut равно значению INFINITE, то время ожидания равно бесконечности.

Аналогичная функция WaitForMultipleObjects ожидает освобождения всех или одного объекта из списка.

Семафоры.

lОбъекты ядра «семафор» используются для учета ресурсов.
lКак и все объекты ядра, они содержат счетчик числа пользователей, но, кроме того, поддерживают два 32-битных значения со знаком: одно определяет максимальное число ресурсов (контролируемое семафором), другое используется как счетчик текущего числа ресурсов.
lДля семафоров определены следующие правила:
lкогда счетчик текущего числа ресурсов становится больше 0, семафор переходит в свободное состояние;
lесли этот счетчик равен 0, семафор занят;
lсистема не допускает присвоения отрицательных значений счетчику текущего числа ресурсов;
lсчетчик текущего числа ресурсов не может быть больше максимального числа ресурсов
lНе путайте счетчик текущего числа ресурсов со счетчиком числа пользователей объекта-семафора!
lС помощью данного объекта можно решать различные проблемы по учету свободных ресурсов, например:
lВы пишете программу, которая, прежде чем дать доступ к набору номера, проверяет, есть ли свободные линии.
lНа момент проверки необходимо приостановить выполнение других потоков, иначе может возникнуть коллизия (в момент выполнения любой команды программы поток может быть приостановлен и квант времени передан другому потоку).
lОбъект ядра «семафор» создается вызовом:

HANDLE CreateSemaphore( PSECURITY_ATTRIBUTE psa, LONG lInitialCount, LONG lMaximumCount, PCTRTR pszName)

lЛюбой процесс может получить свой («процессо-зависимый») описатель существующего объекта «семафор», вызвав

HANDLE OpenSemaphore( DWORD fdwAccess, BOOL bInheritHandle, PCTSTR pszName);

lПараметр lMaximumCount сообщает системе максимальное число ресурсов, обрабатываемое приложением. Поскольку это 32-битное значение со знаком, пре дельное число ресурсов может достигать 2 147 483 647.
lПараметр lInitialCount указывает, сколько из этих ресурсов доступно изначально (на данный момент.

HANDLE hSem = CreateSemaphore(NULL, 0, 5, NULL);

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

BOOL ReleaseSemaphore( HANDLE hSem,

LONG lReleaseCount, PLONG plPreviousCount);

hSem – описатель семафора,
lReleaseCount – определяет, на сколько изменится счетчик ресурсов,
Функция возвращает исходное значение счетчика ресурсов в *plPreviousCount. Если Вас не интересует это значение, передайте в параметре plPreviousCount значение NULL.
Было бы удобнее определять состояние счетчика текущего числа ресурсов, не меняя его значение, но такой функции в Windows нет.

26.12.2015; 23:13
хиты: 0
рейтинг:0
Точные науки
информатика
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь