SetHandleInformation
GetHandleInformation
HANDLE_FLAG_INHERIT
HANDLE_FLAG_PROTECT_FROM_CLOSE (CloseHandle)
Именование:
Можно задать имя:
HANDLE hMut = CreateMutex(NULL, FALSE, “SomeMutex”);
Проводится проверка, имеется ли объект ядра с нашим именем и происходит проверка типа объекта ядра.
Если объект с таким именем и типом уже существует, то функция не создает новый объект, а возвращает описатель существующего объекта (при этом 1-й и 2-й параметры игнорируются) и генерирует код оштбки.
Можно осуществить проверку на возникновение ошибки:
If (GetLastError() = = ERROR_ALREADY_EXISTS) {…}
Пространство имен объектов ядра является глобальным, если только не запущен терминал. В последнем случае к имени добавляются префиксы Global\, Local\.
Дублирование:
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle,//описатель исходного процесса (GetCurrentProcess())
HANDLE hSourceHandle, //дублируемый описатель процесса-источника
HANDLE hTargetProcessHandle, //процесс-приемник
PHANDLE phTargetHandle, //описатель в процессе-приемнике
DWORD dwPesiredAccess,
DWORD dwQotions);
Особенность: нужно использовать механизм межпроцессного взаимодействия для передачи продублированного описателя (DuplicateHandle его сформирует, но нужно также поставить в известность и сам процесс-приемник).
|
|
События
События бывают:
- со сбросом вручную;
- с автоматическим сбросом.
HANDLE CreateEvent (
PSECURITY_ATTRIBUTES sa,
BOOL fManualReset,
BOOL fInitialState,
hPCTSTR name);
BOOL SetEvent (HANDLE); – устанавливает в сигнальное состояние
BOOL ResetEvent (HANDLE); – устанавливает в несигнальном состояние
BOOL PulseEvent (HANDLE); – “комбинация” Set и Reset (устанавливает в сигнальное состояние и сбрасывает в несигнальное)
Если событие с автосбросом, только один поток продолжит исполнение, а если со сбросом вручную – оба потока.
Семафоры
Смысл семафоров – подсчет числа доступных ресурсов (счетчик). Определены 2 операции:
· возврата ресурсов в пул доступных ресурсов (up-операция, v-операция). Увеличивает счетчик.
· захвата ресурсов (down-операция, p-операция).
Если счетчик ресурсов принимает значение 0, то поток блокируется (семафор находится в несигнальном состоянии).
Счетчик не может быть больше максимального числа ресурсов и меньше 0.
CreateSemaphore (
PSECURITY_ATTRIBUTES sa,
LONG lInitialCount,
LONG lMaxCount,
hPCTSTR name);
Операция DOWN:
BOOL ReleaseSemaphore (HANDLE, LONG ReleaseCount);
Мьютексы
Мьютекс, Mutex – от англ. Mutual Exclusion, взаимное исключение.
HANDLE CreateMutex(
PSECURITY_ATTREBUTES sa,
BOOL fInitialOwner,
LPCTSTR name);
BOOL ReleaseMutex (HANDLE);
Мьютекс можно рассматривать как бинарный семафор. Также мьютекс похож и на критическую секцию.
От семафора мьютекс отличается тем, что определено владение мьютексом для захвативших его потоков.
Отличие от критических секций: можно синхронизировать потоки в разных процессах, можно указывать тайм-аут.
|
|
Если поток «владеет» мьютексом, то вызов Wait-функции с этим мьютексом завершится успешно, при этом увеличится внутренний счетчик рекурсий. ReleaseMutex выполняет декремент счетчика рекурсий и освобождает мьютекс, если счетчик достигает «0».
Если попытаться освободить мьютекс из процесса, который им не владеет, то будет ошибка:
GetLastError = ERROR_NOT_OWNED
Если поток, владеющий мьютексом, завершается, то он переходит в несигнальное состояние, может быть использован другими потоками, на Wait-функция вернет ошибку.
GetLastError = WAIT_ABANDONED
Тупики и защита от них
Группа процессов находится в тупиковой ситуации, если каждый процесс из группы ожидает событие, которое может вызвать только другой процесс из этой же группы.
Условия возникновения тупика:
1. Условие взаимного исключения: каждый ресурс отдан или доступен ровно одному процессу.
2. Условие удержания и ожидания: процессы, удерживающие полученные ранее ресурсы, могут запрашивать новые.
3. Условие отсутствия принудительной выгрузки: у процесса нельзя забрать ранее полученный ресурс, процесс, владеющий ресурсом, должен сам освободить его.
4. Условие циклического ожидания: должно существовать 2 или более процессов, каждый из которых ждет доступа к ресурсу, удерживаемому следующим участком последовательности.
Моделирование блокировок, Холт (Holt)
Введем графические обозначения:
Простейший тупик:
|
DWORD Thr1(PVOID){
WaitforSingleObject(T);
WaitforSingleObject(U);
//критическая секция
ReleaseMutex(U);
ReleaseMutex(T); }