Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование RegisterWaitForSingleObject, для "многократного" ожидания событий 
:(
    Опции темы
Riply
Дата 29.3.2007, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 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. smile
Вариант второй:
Вызываем ее с флагом WT_EXECUTEONLYONCE.
Здесь все работает, но есть очень большое "но".
После каждого удачного вызова WaitObjectCallBack, мы должны
снимать регистрацию нашего события ( UnregisterWait ) и заново его регистрировать. 
А мне кажется, что это вряд ли способствует оптимальному использованию ресурсов smile
Как бы исхитриться и остановиться на первом варианте, 
но с одним вызовом WaitObjectCallBack для каждого срабатывания нашего события ?
P.S. Создать некий индикатор "повторности вызова" и проверять его - (как мне кажется) не выход.

PM MAIL   Вверх
bems
Дата 30.3.2007, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



Трудно понять чего именно ты хочешь, но прискну предположить что тебе поможет событие с автосбросом. Тогда ResetEvent вызывается до вызова твоего калбека


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Riply
Дата 30.3.2007, 01:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



> bems
>"Трудно понять чего именно ты хочешь"
К сожалению, мои объяснения часто получаются сумбурными. :(
Попробую еще раз.
Есть n объектов. Их количество в процессе работы меняется и может оказаться
больше чем MAXIMUM_WAIT_OBJECTS. Нужно при "срабатывании"
любого из них, например, активизировать нить для обработки(или напрямую что-то выполнить) 
и вернуться к ожиданию.   
Как мне кажется, что RegisterWaitForSingleObject подходит для этого.
"Автосбрасываемый" Event - решение хорошее, но, в данном случае, не подходит :(
Т.к. WaitForMultipleObjects, которая внутри RegisterWaitForSingleObject,
(точнее одна из них) может не успеть сработать. Например, если в 
данный момент времени "основная" нить RegisterWaitForSingleObject, чем-то занята.

PM MAIL   Вверх
bems
Дата 30.3.2007, 02:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



Цитата(Riply @  30.3.2007,  01:11 Найти цитируемый пост)
"Автосбрасываемый" Event - решение хорошее, но, в данном случае, не подходит :(
Т.к. WaitForMultipleObjects, которая внутри RegisterWaitForSingleObject,
(точнее одна из них) может не успеть сработать. Например, если в 
данный момент времени "основная" нить RegisterWaitForSingleObject, чем-то занята.


Нить, кторая вызвала  RegisterWaitForSingleObject будет выполнять твою функцию только если указан флаг WT_EXECUTEINWAITTHREAD. В первом посте ты отказался от этого флага следовательно от (не)занятости вызывающего потока колбэк не зависит, а выполняться он будет в потоке, управляемом системой (если один колбэк уже выполняется, то система предоставит другой поток).
"WaitForMultipleObjects, которая внутри RegisterWaitForSingleObject" вызывается не потоком, который вызвал RegisterWaitForSingleObject, а каким-то другим (ты его вообще напрямую не создаешь)

Относительно события с автосбросом, то это более првильный вариант, т.к. в описании функции можно найти это:
Цитата

Note that you should not pulse an event object passed to RegisterWaitForSingleObject, because the wait thread might not detect that the event is signaled before it is reset. You should not register a an object that remains signaled (such as a manual reset event or terminated process) unless you set the WT_EXECUTEONLYONCE or WT_EXECUTEINWAITTHREAD flag.
Поскольку ни один из этих флагов тебе не подходит, можно сделать вывод, что если это событие - то только с автосбросом

Цитата(Riply @  30.3.2007,  01:11 Найти цитируемый пост)
WaitForMultipleObjects, которая внутри RegisterWaitForSingleObject,(точнее одна из них) может не успеть сработать

наоборот - гарантия вызова колбека для каждого изменения состояния объекта
Другой вопрос - реентерабельна ли твоя колбек-функция. Например это 
with PWaitThreadParam(pParam)^ 
намекает на неприятности, но все конечно зависит от того, что внутри with-блока



Короче вырыжаясь: при событии с автосбросом функция вызывается гарантировано каждый раз, но потенцияльно работает в нескольких потоках одновременно, и тебе решать как нужно (и нужно ли) управляться из нее с общими ресурсами


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Riply
Дата 30.3.2007, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Большое спасибо за детальные разъяснеия.
После них, многое встало на свои места.
P.S.
 Очередной раз вынуждена признать, 
 что утверждение "подумать - иногда, не вредно" - истинно smile 
PM MAIL   Вверх
bems
Дата 31.3.2007, 00:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



Цитата(Riply @  30.3.2007,  16:05 Найти цитируемый пост)
вынуждена 
ой...
Цитата(bems @  30.3.2007,  02:46 Найти цитируемый пост)
ты отказался от
за это извини, мне очень стыдно...
 smile  smile 


Цитата(Riply @  30.3.2007,  16:05 Найти цитируемый пост)
Очередной раз вынуждена признать, 
 что утверждение "подумать - иногда, не вредно" - истинно 
почитать МыСыДыНы тоже полезно...  smile

Добавлено через 6 минут и 57 секунд
Хоть помогло?

Если проблемы продолжаются - дай больше кода, разберемся по контексту, а вдруг че и придумаем...


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Riply
Дата 31.3.2007, 02:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



bems, 
Цитата

за это извини, мне очень стыдно...

"К иcкусству, котрое я в данный момент представляю, это не имеет никакого отношения"
(с) (Иван Васильевич меняет профессию).   smile 
Цитата

почитать МыСыДыНы тоже полезно...
 Да... уж...   smile 
Цитата

Хоть помогло?

Да. Спасибо. Как ни странно, но работает. Бывает же smile 
Цитата

Если проблемы продолжаются - дай больше кода, разберемся по контексту

Пока нерешаемых самостоятельно не возникло, но пользуясь случаем, вдогонку, еще один вопрос:
После окончания работы с пулом (окончание - все, что надо отловили, все объекты "сняли с регистрации"),
остается "висеть" несколько нитей (количество зависит от интенсивности работы пула и кол-ва объектов).
Существует ли способ их завершить ? Или часть из них так и останется до завершения процесса ?
P.S. Не варварским способом типа TerminateThread, а объяснить системе, что они больше не нужны  smile 
PM MAIL   Вверх
bems
Дата 31.3.2007, 03:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



После вызова  UnregisterWait/UnregisterWaitEx остаются? Тогда наверное это запас на будущее или не завершенный "естественным" путем колбэк

тогда уж не знаю...


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Riply
Дата 31.3.2007, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(bems @  31.3.2007,  03:09 Найти цитируемый пост)
После вызова  UnregisterWait/UnregisterWaitEx остаются? Тогда наверное это запас на будущее или не завершенный "естественным" путем колбэк

UnregisterWaitEx вызывался параметром INVALID_HANDLE_VALUE
В "колбэке" только Sleep(10);
Кроме одного исчезают минут через пять.
Будем считать что система очень запаслива  smile 
Еще раз спаибо.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1820 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.