![]() |
|
Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply |
![]()
|
|
| Riply |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Комодератор Сообщений: 572 Регистрация: 27.3.2007 Где: St. Petersburg Репутация: 21 Всего: 32 |
Здравствуйте !
Задача такая: отслеживать неоднократное "срабатывание" большого кол-ва объектов. Пытаюсь воспользоваться сабжевой функцией и (как всегда) встречаю проблемы. Допустим, мы решили поступить так: Вызываем ее с неким флагом (не WT_EXECUTEINWAITTHREAD т.к. CallBack может занять некоторое время), и с CallBack, примерно такого вида: procedure WaitObjectCallBack(pParam: Pointer; TimerOrWaitFired: Boolean); stdcall; begin with PWaitThreadParam(pParam)^ do // WaitThreadParam - нами определенная стуктура. try ResetEvent(hEvent); // Здесь hEvent - Handle нашего события, которого ждали. Этот вариант плох тем, что WaitObjectCallBack может быть вызвана 138 раз, прежде чем мы успеем вызвать ResetEvent. Вариант второй: Вызываем ее с флагом WT_EXECUTEONLYONCE. Здесь все работает, но есть очень большое "но". После каждого удачного вызова WaitObjectCallBack, мы должны снимать регистрацию нашего события ( UnregisterWait ) и заново его регистрировать. А мне кажется, что это вряд ли способствует оптимальному использованию ресурсов Как бы исхитриться и остановиться на первом варианте, но с одним вызовом WaitObjectCallBack для каждого срабатывания нашего события ? P.S. Создать некий индикатор "повторности вызова" и проверять его - (как мне кажется) не выход. |
|||
|
||||
| bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
Трудно понять чего именно ты хочешь, но прискну предположить что тебе поможет событие с автосбросом. Тогда ResetEvent вызывается до вызова твоего калбека
-------------------- Обижено школьников: 8 |
|||
|
||||
| Riply |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Комодератор Сообщений: 572 Регистрация: 27.3.2007 Где: St. Petersburg Репутация: 21 Всего: 32 |
> bems
>"Трудно понять чего именно ты хочешь" К сожалению, мои объяснения часто получаются сумбурными. :( Попробую еще раз. Есть n объектов. Их количество в процессе работы меняется и может оказаться больше чем MAXIMUM_WAIT_OBJECTS. Нужно при "срабатывании" любого из них, например, активизировать нить для обработки(или напрямую что-то выполнить) и вернуться к ожиданию. Как мне кажется, что RegisterWaitForSingleObject подходит для этого. "Автосбрасываемый" Event - решение хорошее, но, в данном случае, не подходит :( Т.к. WaitForMultipleObjects, которая внутри RegisterWaitForSingleObject, (точнее одна из них) может не успеть сработать. Например, если в данный момент времени "основная" нить RegisterWaitForSingleObject, чем-то занята. |
|||
|
||||
| bems |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
Нить, кторая вызвала RegisterWaitForSingleObject будет выполнять твою функцию только если указан флаг WT_EXECUTEINWAITTHREAD. В первом посте ты отказался от этого флага следовательно от (не)занятости вызывающего потока колбэк не зависит, а выполняться он будет в потоке, управляемом системой (если один колбэк уже выполняется, то система предоставит другой поток). "WaitForMultipleObjects, которая внутри RegisterWaitForSingleObject" вызывается не потоком, который вызвал RegisterWaitForSingleObject, а каким-то другим (ты его вообще напрямую не создаешь) Относительно события с автосбросом, то это более првильный вариант, т.к. в описании функции можно найти это:
наоборот - гарантия вызова колбека для каждого изменения состояния объекта Другой вопрос - реентерабельна ли твоя колбек-функция. Например это with PWaitThreadParam(pParam)^ намекает на неприятности, но все конечно зависит от того, что внутри with-блока Короче вырыжаясь: при событии с автосбросом функция вызывается гарантировано каждый раз, но потенцияльно работает в нескольких потоках одновременно, и тебе решать как нужно (и нужно ли) управляться из нее с общими ресурсами -------------------- Обижено школьников: 8 |
||||
|
|||||
| Riply |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Комодератор Сообщений: 572 Регистрация: 27.3.2007 Где: St. Petersburg Репутация: 21 Всего: 32 |
Большое спасибо за детальные разъяснеия.
После них, многое встало на свои места. P.S. Очередной раз вынуждена признать, что утверждение "подумать - иногда, не вредно" - истинно |
|||
|
||||
| bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
ой...
за это извини, мне очень стыдно...
Добавлено через 6 минут и 57 секунд Хоть помогло? Если проблемы продолжаются - дай больше кода, разберемся по контексту, а вдруг че и придумаем... -------------------- Обижено школьников: 8 |
|||
|
||||
| Riply |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Комодератор Сообщений: 572 Регистрация: 27.3.2007 Где: St. Petersburg Репутация: 21 Всего: 32 |
bems,
"К иcкусству, котрое я в данный момент представляю, это не имеет никакого отношения" (с) (Иван Васильевич меняет профессию).
Да. Спасибо. Как ни странно, но работает. Бывает же
Пока нерешаемых самостоятельно не возникло, но пользуясь случаем, вдогонку, еще один вопрос: После окончания работы с пулом (окончание - все, что надо отловили, все объекты "сняли с регистрации"), остается "висеть" несколько нитей (количество зависит от интенсивности работы пула и кол-ва объектов). Существует ли способ их завершить ? Или часть из них так и останется до завершения процесса ? P.S. Не варварским способом типа TerminateThread, а объяснить системе, что они больше не нужны |
||||||||
|
|||||||||
| bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
После вызова UnregisterWait/UnregisterWaitEx остаются? Тогда наверное это запас на будущее или не завершенный "естественным" путем колбэк
тогда уж не знаю... -------------------- Обижено школьников: 8 |
|||
|
||||
| Riply |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Комодератор Сообщений: 572 Регистрация: 27.3.2007 Где: St. Petersburg Репутация: 21 Всего: 32 |
UnregisterWaitEx вызывался параметром INVALID_HANDLE_VALUE В "колбэке" только Sleep(10); Кроме одного исчезают минут через пять. Будем считать что система очень запаслива Еще раз спаибо. |
|||
|
||||
![]()
|
| Правила форума "Delphi: WinAPI и системное программирование" | |
|
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |