- •Глава 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).
- •Анонимный канал
- •Создание анонимных каналов
- •Соединение клиентов с анонимным каналом
- •Обмен данными по анонимному каналу
- •Именованный канал
- •Функция создания именованного канала
- •Функция соединения сервера с клиентом
- •Отключение сервера от клиента
- •Функция ожидания операции именованного канала
- •Функция объединения функций именованного канала
- •Подключение клиента к серверу
§5. Синхронизация задач с помощью объектов ядра «уведомление об изменении» (Change Notification).
Уведомление об изменении — объект, который переходит в сигнальное состояние при изменении содержимого каталога на диске.
Функция создания объекта ядра «уведомление об изменении»
HANDLE FindFirstChangeNotification(
IN LPCSTR lpPathName,
IN BOOL bWatchSub,
IN DWORD dwNotifyFilter
);
Параметры и описание:
(1) lpPathName — определяет полный путь к каталогу для просмотра. Не может содержать относительный путь или пустую строку.
(2) bWatchSub — определяет отслеживание подкаталогов. Если TRUE, то функция отслеживает изменения в подкаталогах. Если FALSE, то отслеживает только в указанном каталоге.
(3) dwNotifyFilter — определяет фильтр изменений.
Принимает следующие значения:
— FILE_NOTIFY_CHANGE_FILE_NAME (0x00000001) — любое изменение имени файла в наблюдаемом каталоге или поддереве. Изменения включают переименование, создание или удаление имени файла.
— FILE_NOTIFY_CHANGE_DIR_NAME (0x00000002) — любое изменение имени каталога в наблюдаемом каталоге или поддереве. Изменения включают создание или удаление каталога.
— FILE_NOTIFY_CHANGE_ATTRIBUTES (0x00000004) — любое изменение атрибута в наблюдаемом каталоге или поддереве.
— FILE_NOTIFY_CHANGE_SIZE (0x00000008) — любое изменение размера файла в наблюдаемом каталоге или поддереве.
— FILE_NOTIFY_CHANGE_LAST_WRITE (0x00000010) — любое изменение последнего времени записи файлов в наблюдаемом каталоге или поддереве.
— FILE_NOTIFY_CHANGE_SECURITY (0x00000100) — любое изменение дескриптора безопасности в наблюдаемом каталоге или поддереве.
Возвращаемое значение.
Если функция завершилась успешно, она возвращает дескриптор объекта уведомления об изменении, в противном случае — возвращает INVALID_HANDLE_VALUE.
Описание.
При помощи функций ожидания (например, WaitForSingleObject) можно отслеживать указанный каталог или поддерево, используя дескриптор, возвращаемый функцией FindFirstChangeNotification. Когда одно из условий фильтрации «срабатывает» в отслеживаемом каталоге или поддереве, объект переходит в сигнальное состояние. После этого приложение может ответить на это условие и продолжить мониторинг каталога, вызвав функцию FindNextChangeNotification и соответствующую функцию ожидания. Когда дескриптор больше не нужен, его нужно закрыть с помощью функции FindCloseChangeNotification.
Функция перезапуска объекта ядра «уведомление об изменении»
BOOL FindNextChangeNotification(
IN HANDLE hChangeHandle
);
Параметры и описание:
(1) hChangeHandle — дескриптор уведомления об изменении, созданный функцией FindFirstChangeNotification.
Возвращаемое значение.
Если функция завершилась успешно, она возвращает TRUE, в противном случае — FALSE.
Функция остановки мониторинга дескриптора объекта ядра «уведомление об изменении»
BOOL FindCloseChangeNotification(
IN HANDLE hChangeHandle
);
Параметры и описание:
(1) hChangeHandle — дескриптор уведомления об изменении, созданный функцией FindFirstChangeNotification.
Возвращаемое значение.
Если функция завершилась успешно, она возвращает TRUE, в противном случае — FALSE.
Пример (C).
Программа ждет 15 секунд какого-либо события с невложенными папками диска C. Если событие происходит менее, чем за 15 секунд, то вывод сообщения на экран "Действие с папкой. Продолжить?", если же за 15 секунд ничего с папками не происходит, то программа завершается (время ожидания истекло).
После каждого события программа спрашивает пользователя о продолжении отслеживания. Если пользователь пишет "n" (нет), то программа завершается, иначе продолжает свою работу.
#include <stdio.h>
#include <locale.h>
#include <windows.h>
int main() {
setlocale(LC_ALL, "Russian");
HANDLE hChNotify = FindFirstChangeNotification("C:\\", FALSE, FILE_NOTIFY_CHANGE_DIR_NAME); /// Проверяем невложенные папки диска C
if (hChNotify == INVALID_HANDLE_VALUE) {
printf("Ошибка. Неверное значение дескриптора!");
return 1;
}
printf("Ждем изменений\n");
/// Ждем на протяжении 15 секунд. Если ничего не изменится, то выход из программы.
DWORD dwWaitNotify = WaitForSingleObject(hChNotify, 15000);
switch (dwWaitNotify) {
case WAIT_TIMEOUT : printf ("Время ожидания истекло\nВыход\n"); return 2;
}
while (true) {
printf("Действие с папкой. Продолжить?\n");
if (getchar() == 'n') /// Считываем первый символ
break;
while (getchar() != '\n') continue; /// Остальные пропускаем
if (!FindNextChangeNotification(hChNotify)) break;
printf("Ждем изменений\n");
/// Ждем на протяжении 15 секунд. Если ничего не изменится, то выход из программы.
dwWaitNotify = WaitForSingleObject(hChNotify, 15000);
switch (dwWaitNotify) {
case WAIT_TIMEOUT : printf ("Время ожидания истекло\nВыход\n"); return 2;
}
}
FindCloseChangeNotification(hChNotify); /// Закрываем
CloseHandle(hChNotify); /// Закрываем
Sleep(1000); /// Чуть-чуть поспим перед выходом
return 0;
}