DWORD WINAPI StartMonitoringDirectory(HANDLE hDirectory) {
DWORD dwBytesRead = 0, dwWaitState = 0;
OVERLAPPED overlapped = {0};
HANDLE hCloseRequestEvent = ....; // запрос на прерывание мониторинга
HANDLE hSuspendRequestEvent = ....; // запрос на паузу мониторинга
HANDLE hSuspendedEvent = ....; // мониторинг приостановлен
HANDLE hResumeRequestEvent = ....; // запрос на восстановление мониторинга
HANDLE hResumedEvent = ....; // мониторинг восстановлен
HANDLES hEventsToWait[4] = {hCloseRequestEvent, hSuspendRequestEvent, hResumeRequestEvent, (HANDLE)NULL};
while (true) {
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // асинхронное чтение
hEventsToWait[3] = overlapped.hEvent;
if (WaitForSingleObject(hSuspendedEvent, 0) != WAIT_OBJECT_0) // если мониторинг не приостановлен
ReadDirectoryChangesW(hDirectory, lpBuffer, READ_CHANGES_BUF_SIZE, FALSE, FILE_NOTIFY_CHANGE_SECURITY | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME, &dwBytesRead, &overlapped, NULL);
dwWaitState = WaitForMultipleObject(4, hEventsToWait, FALSE /* ждать хотя бы одного события */, INFINITE);
switch(dwWaitState) {
case WAIT_OBJECT_0: // запрос на закрытие
CloseHandle(overlapped.hEvent);
ExitThread(0);
return;
case WAIT_OBJECT_0 + 1: // запрос на приостановку
ResetEvent(hSuspendRequestEvent);
ResetEvent(hResumeRequestEvent);
ResetEvent(hResumedEvent);
SetEvent(hSuspendedEvent);
case WAIT_OBJECT_0 + 2: // запрос на восстановление
ResetEvent(hResumeRequestEvent);
ResetEvent(hSuspendRequestEvent);
ResetEvent(hSuspendedEvent);
SetEvent(hResumedEvent);
break;
case WAIT_OBJECT_0 + 3: // уведомление об изменение в каталоге
// обработать
break;
default:
CloseHandle(overlapped.hEvent);
ExitThread(1);
}
CloseHandle(overlapped.hEvent);
}
}
ReadDirectoryChangesW() под нагрузкой
Возник вопрос по сабжу. До последнего не хотел сюда постить, но в конце концов решил спросить хотя бы, кто что думает.
Ситуация следующая. Есть приложение, которое мониторит несколько каталогов с помощью ReadDirectoryChangesW(). Каждому каталогу выделен отдельный поток следующей структуры:
Код:
Приведенная конструкция работает правильно, но когда файлы в каталоге меняются сравнительно быстро, происходят какие-то совершенно непонятные "подвисания" на этапе обработки. Сталкивался ли кто-нибудь с особенностями работы ReadDirectoryChangesW() под нагрузкой? Или мне идти и лучше искать свой косяк?
Буфер, который передается для возврата данных об изменениях какого размера? И не много ли евентов? у меня в одном проекте 256К и всего 2 евента - 1 для ридера и 1 для управления работой, так как логика работы описана по другому и мониторя весь C: никаких проблем с подвисаниями и пропусками не обнаружено, даже на слабых машинах...
А будут какие-то предложения по общей логике работы? Повторюсь, я допускаю, что это мой баг, но пока категорически не вижу возможных мест его возникновения.
Я замечал подобное на стадии изучения этих механизмов, по этому когда писал то, о чем говорил ранее, сделал именно так - 1 поток на весь диск без ограничения по составу и отработка инфы на предмет анализа - этот файл мне интересен или нет...
[QUOTE=Yos]
по этому когда писал то, о чем говорил ранее, сделал именно так - 1 поток на весь диск без ограничения по составу и отработка инфы на предмет анализа - этот файл мне интересен или нет...
[/QUOTE]
К сожалению, в моем случае просто так сделать не получится, потому что мониторятся файлы с разных дисков и с разных компьютеров, которые могут (в принципе) обновляться достаточно быстро. Соответственно, проверять каждый изменившийся файл на "интересность" - довольно дорогое удовольствие в рамках моей задачи.
У меня буквально полчаса назад появилась другая идея: можно попытаться для каждого файла, который подлежит мониторингу, создавать ярлык в некоей временной папке и мониторить только эту одну папку. Проблема здесь в том, что lnk-файл ярлыка, по идее, не изменяется при изменении того файла, на который он ссылается, но это я еще посмотрю поподробнее.
P.S. Пока включил просто перехват изменения последнего времени модификации файла по таймеру, работает нормально.
lnk-файл имхо глупость, уж лучше тогда hardlink.
Да, разумеется, с симлинком я дал маху. Конечно, hardlink лучше, тут без вопросов.
Цитата: Alexander92
Да, разумеется, с симлинком я дал маху. Конечно, hardlink лучше, тут без вопросов.
lnk-файл, это никаким боком не симлинк, а обычный файл, который виндовый шелл обрабатывает.
А, собственно, симлинки на NTFS можно создавать только к папкам.
kissko, я понимаю это все. Прошу прощения за неточную терминологию.