Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СППО .doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
190.46 Кб
Скачать

Wait-функции

Wait-функции позволяют потоку в любой момент приостановиться и ждать освобождения какого-либо объекта ядра. Из всего семейства этих функций чаще всего используется WaitForSingleObject:

DWORD WaitForSingleObject( HANDLE hObject, DWORD dwMilliseconds);

Когда поток вызывает эту функцию, первый параметр, hObject, идентифицирует объект ядра, поддерживающий состояния "свободен-занят" (То есть любой объект, упомянутый в списке из предыдущего раздела.) Второй параметр, dwMilliseconds, указывает, сколько времени (в миллисекундах) поток готов ждать освобождения объекта.

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

WaitForSingleObject(hProcess, INFINITE);

В данном случае константа INFINITE, передаваемая во втором параметре, подсказывает системе, что вызывающий поток готов ждать этого события хоть целую вечность. Именно эта константа обычно и передается функции WaitForSingleObject, но Вы можете указать любое значение в миллисекундах.

Возвращаемое значение функции WaitForSingleObject указывает, почему вызывающий поток снова стал планируемым Если функция возвращает WAIT_OBTECT_0, объект свободен, а если WAIT_TIMEOUT — заданное время ожидания (таймаут) истекло. При передаче неверного параметра (например, недопустимого описателя) WaitForSing leObject возвращает WAIT_ EAILED. Чтобы выяснить конкретную причину ошибки, вы зовите функцию GetLastErroY.

Функция WaitForMultipleObjects аналогична WaitForSingleObject c тем исключением, что позволяет ждать освобождения сразу нескольких объектов или какого-то одного из списка объектов:

DWORD WaitForMultipleObjects( DWOHD dwCount, CONST HANDLE* phObjects, BOOL fWaitAll, DWORD dwMilliseconds);

Параметр dwCount определяет количество интересующих Вас объектов ядра Его значениедолжло быть в пределах от 1 до MAXIMUM_WAIT_OBJECTS (в заголовочных файлах Windows оно определено как 64). Параметр phObject — это указатель на массив описателей объектов ядра.

WaitForMultipleObjects приостанавливает поток и заставляет его ждать освобождения либо всех заданных объектов ядра, либо одного из них. Параметр fWaitAll как раз и определяет, чего именно Вы хотите от функции. Если он равен TRUE, функция не даст потоку возобновить свою работу, пока не освободятся все объекты.

Параметр dwMilliseconds идентичен одноименному параметру функции WaitFor SingleObject.

14. Семафоры, мьютексы, события

Мьютексы

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

Мьютекс создается функцией

function CreateMutex(

Attr: Pointer; // указатель на атрибуты безопасности

flag: Boolean; // флаг создания

lpName: PChar // имя мьютекса (обычно Nil, если мьютекс // используется только внутри одного процесса)

): THandle; // дескриптор мьютекса

Флаг создания указывает (True), будет ли процесс владеть мьютексом сразу после его создания. Функция возвращает дескриптор созданного объекта, либо 0. Если мьютекс с заданным именем уже был создан, возвращается его дескриптор.

Проверить, был объект создан, или используется уже существующий можно следующим образом:

hMutex := CreateMutex (NIL, FALSE, ‘MutexName’); if hMutex = 0 then RaiseLastWin32Error; if GetLastError = ERROR_ALREADY_EXISTS then begin // Используем ранее созданный объект end;

Мьютексы могут находиться в сигнальном (если им не владеет ни один поток, т.е. ресурс свободен) или несигнальном состоянии (поток владеет мьютексом). Чтобы поток завладел мьютексом (т.е. получил доступ к ресурсу), необходимо вызвать функцию ожидания

function WaitForSingleObject(

hHandle: THandle; // дескриптор мьютекса

dwMilliseconds: DWord // время ожидания в мс

): DWord;

Параметр dwMilliseconds может принимать значение Infinite, что означает бесконечный интервал ожидания.

Функция завершает работу, если мьютекс становится сигнальным или истекло время ожидания. После этого поток, находящийся в состоянии ожидания мьютекса, получает к нему доступ, а мьютекс, получивший нового владельца, перестает сигнализировать. Мьютекс можно сравнить с «эстафетной палочкой», которую бегун (поток) молча держит, проходя дистанцию, и кричит «Держи!» (сигнализирует), завершив дистанцию. Вместо WaitForSingleObject может также применяться функция WaitForMultipleObjects [3], которая завершает работу, если несколько мьютексов перешли в сигнальное состояние.

После того, как поток выполнил участок кода, содержащий совместно используемый ресурс, необходимо освободить мьютекс от потока-владельца с помощью функции API

function ReleaseMutex(

hHandle: THandle; // дескриптор мьютекса

): Boolean;

При завершении работы мьютекс удаляется из памяти с помощью известной Вам функции CloseHandle, в которую передается дескриптор мьютекса.

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

Семафоры

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