- •Глава 2. Синхронизация задач с использованием api-функций и механизмов ядра.
- •§0. Объекты ядра. Основы.
- •Учет пользователей объектов ядра
- •Процесс и поток: краткая характеристика
- •Создание объекта ядра
- •Закрытие объекта ядра
- •Синхронизация объектов
- •Наследование описателей объекта
- •Именованные объекты
- •3. После этого вызова система проверяет, существует ли уже объект ядра с таким же именем. Если существует, то
- •Open-функции
- •Дублирование описателей объектов
- •1) Процесс-катализатор.
- •2) Процесс-источник.
- •3) Процесс-приемник.
- •Исходное состояние
- •1 0XF0000000 (неприм.) (неприм.)
- •1 0XF0000000 (неприм.) (неприм.)
- •Состояние после вызова DuplicateHandle
- •§1. Синхронизация задач с использованием функций ожидания.
- •Функция ожидания одного объекта
- •Функция ожидания нескольких объектов
- •Функция ожидания нескольких объектов и сообщений
- •Функция создания дочернего процесса
- •Функция завершения дочернего процесса из самого дочернего процесса
- •Функция завершения дочернего процесса из процесса родителя
- •Функция создания вторичного потока
- •Функция завершения дочернего потока из самого дочернего потока (only c)
- •Функция завершения дочернего потока из потока родителя
- •If (my_file.Is_open()) { /// Если удалось открыть
- •Функция создания вторичного потока _beginthread
- •Функция создания вторичного потока _beginthreadex
- •§2. Синхронизация задач с помощью объектов ядра «событие» (Event).
- •Функция создания события
- •Функция установки сигнального состояния события
- •Функция установки несигнального состояния события
- •Функция открытия существующего именованного объекта события
- •Дескриптор защиты (структура)
- •§3. Синхронизация задач с помощью объектов ядра «семафор» (Semaphore).
- •Функция создания семафора
- •Функция открытия семафора
- •Функция увеличения счетчика семафора на указанное количество
- •If (!ReleaseSemaphore( ghSemaphore, 1, null)) /// Если ошибка
- •§4. Синхронизация задач с помощью объектов ядра «мьютекс» (Mutex).
- •Функция создания мьютекса
- •Функция открытия существующего именованного объекта мьютекса
- •Функция освобождения владельца указанного объекта мьютекса
- •§5. Синхронизация задач с помощью объектов ядра «уведомление об изменении» (Change Notification).
- •Функция создания объекта ядра «уведомление об изменении»
- •Функция перезапуска объекта ядра «уведомление об изменении»
- •Функция остановки мониторинга дескриптора объекта ядра «уведомление об изменении»
- •§6. Синхронизация задач с помощью объектов ядра «таймер ожидания» (Waitable Timer).
- •Функция создания объекта ядра «таймер ожидания»
- •Функция активации объекта ядра «ожидаемый таймер»
- •Функция открытия объекта ядра «ожидаемый таймер»
- •1. Функцией CancelWaitableTimer().
- •2. Функцией SetWaitableTimer().
- •If (bSuccess) /// Если успешно, то
- •If (bSuccess) /// Если успешно, то
- •§7. Синхронизация задач с помощью объектов ядра «канал» (Pipe).
- •Анонимный канал
- •Создание анонимных каналов
- •Соединение клиентов с анонимным каналом
- •Обмен данными по анонимному каналу
- •Именованный канал
- •Функция создания именованного канала
- •Функция соединения сервера с клиентом
- •Отключение сервера от клиента
- •Функция ожидания операции именованного канала
- •Функция объединения функций именованного канала
- •Подключение клиента к серверу
1 0XF0000000 (неприм.) (неприм.)
2 0xF0000030 0x???????? 0x00000000
Как видно, процесс-приемник содержит только одну запись со значением индекса, равным 2.
неприм. — неприменим
0xF0000030 идентифицирует объект ядра любого типа.
Состояние после вызова DuplicateHandle
Процесс-катализатор вызывает функцию:
DuplicateHandle(1, 2, 2, &hObj, 0, TRUE, DUPLICATE_SAME_ACCESS);
Изменится только таблица описателей в процессе-приемнике.
Индекс Указатель Маска Флаги
1 0xF0000020 0x???????? 0x00000001
2 0xF0000030 0x???????? 0x00000000
Вторая строка таблицы описателей в процессе-источнике скопирована в первую строку таблицы описателей в процессе-приемнике.
Заметьте, что система установила битовый флаг наследования, так как в параметре bInheritHandle функции DuplicateHandle мы передали TRUE.
Функция DuplicateHandle присвоила также переменной bObj процесса-приемника значение 1 — индекс той строки таблицы в процессе-приемнике, в которую занесен новый описатель.
Поскольку функции DuplicateHandle передан флаг DUPLICATE_SAME_ACCESS, маска доступа для этого описателя в процессе-приемнике идентична маске доступа в процессе-источнике. Кроме того, данный флаг заставляет DuplicateHandle проигнорировать параметр dwDesiredAccess.
В реальных программах значения описателей хранятся в переменных и, конечно же, именно эти переменные передаются функциям.
Как и механизм наследования, функция DuplicateHandle тоже обладает одной странностью: процесс-приемник никак не уведомляется о том, что он получил доступ к новому объекту ядра. А раз процессы уже запущены, то в таком случае придется либо послать сообщение окну, либо задействовать какой-нибудь другой механизм межпроцессной связи.
§1. Синхронизация задач с использованием функций ожидания.
Wait-функции (функции ожидания) позволяют потоку в любой момент приостановиться и подождать освобождения (перехода в сигнальное состояние) какого-либо объекта ядра.
Функция ожидания одного объекта
DWORD WaitForSingleObject(
IN HANDLE hHandle,
IN DWORD dwMilliseconds
);
Краткое описание.
Функция WaitForSingleObjects ждет до тех пор, пока указанный объект не окажется в сигнальном состоянии или пока не истечет время ожидания.
Параметры и описание:
(1) hHandle идентифицирует объект ядра (имеет состояния «свободен-занят»). Функция может указывать дескриптор любого из следующих типов объектов: (1) уведомление об изменении, (2) консольный ввод, (3) событие, (4) мьютекс, (5) процесс, (6) семафор, (7) поток, (8) ожидаемый таймер, (9) уведомление о ресурсе памяти.
(2) dwMilliseconds указывает, сколько времени поток готов ждать освобождения объекта.
Если dwMilliseconds равен 0, то функция проверяет состояние объекта и возвращает результат сразу.
Если dwMilliseconds равен INFINITE (в 16-ричной: 0xFFFFFFFF или в 10-тичной 32-битной: –1), то функция завершает свою работу при переходе объекта в сигнальное состояние или ждёт завершения очень большого интервала INFINITE.
Возвращаемое значение:
— WAIT_OBJECT_0 (0x00000000L)
Сигнальное состояние. Процесс завершается.
— WAIT_ABANDONED (0x00000080L)
(Abandoned — (за)брошенный)
Указанный объект является объектом мьютекса, который не был освобожден потоком. Состояние мьютекса — несигнальное.
— WAIT_TIMEOUT (0x00000102L)
Время ожидания истекло. Объект так и не перешел в сигнальное состояние.
— WAIT_FAILED (0xFFFFFFFF)
Функция не выполнена (ошибка).
Дополнительная информация.
Будьте осторожны при вызове функций ожидания и кода, который прямо или косвенно создает окна. Поток, использующий функцию ожидания без интервала времени ожидания, может привести к зависанию системы. Поэтому, если у вас есть поток, который создает окна, используйте MsgWaitForMultipleObjects.