Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: watchdog - с чем его едят?  (Прочитано 45851 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« : 22-04-2010 13:58 » 

Господа,
кто-нибудь сталкивался с этим предметом? Где бы посмотреть пример (лучше на с#) или описание алгоритма?  Здесь была моя ладья...
Общее описание я прочла, но посмотреть бы на примерную реализацию...
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 22-04-2010 14:00 » 

Программный watchdog?

Где мои 1725 лет?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 22-04-2010 14:08 » 

Алгоритм достаточно прост.

Инициализация таймера watchdog.


Программный код.

Выполнение кода в цикле. Каждый цикл watchdog переинициализируется.
В случае зацикливания, или же по какой-либо причине не происходит перезапуск "собаки" Все начинается с "нуля"


Это на пальцах.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #3 : 22-04-2010 14:19 » 

Слав,
ну и где они, твои 25 лет? А заодно и мои тоже?  Улыбаюсь)

Ага, видимо, программный (т.е. с железом ничего общего не имеет).
Суть задачки:
Есть тест, который для своей работы стартует парочку других ехе-шников (как процессы). Так вот иногда один из этих процессов зависает, что приводит к общему зависанию теста.
Появилась идея написать эту самую собаку, которая следила бы за тестом и в случае зависания давала бы команду "убить Билла" Ага , т.е. killProcess.

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

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 22-04-2010 14:22 » 

Sla, замутил чего-то.

Что значит "в случае зацикливания", если все и так крутится в цикле?
"С нуля" всё начинается, как раз тогда когда сброс (или как у тебя "перезапуск") происходит. А если он НЕ происходит, то отслеживаемая система считается повисшей (неработоспособной, не успевающей и т.д.).
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 22-04-2010 14:25 » 

Не забывай, бывают моменты что время выполнения некоторых тестов может быть больше времени перезапуска собаки. Для этого из теста нужно посылать собаке информацию о том, что процесс скорее жив, чем мертв.

У нас была подобного рода система. Но она была программно-аппаратным  комплексом.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 22-04-2010 14:26 » 

resource, под зацикливанием понимался не основной процесс, а второстепенный.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #7 : 22-04-2010 15:29 » 

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

Есть основной процесс - тест.длл.
1) куда помещаем сторожа? Надо создавать отдельную длл-лину или это класс в нашем тесте?
2) если стартуем и убиваем таймер в тесте, как это связано со сторожем ?
Такое ощущение, что я что-то не так понимаю...

По моей логике:

тест                                                        сторож

 
                           StartTimer(30 sec)
                           Event1 = CreateEvent(autoreset)


                           OnTimer():
                            - SetEvent(Event1)
                            - SendMsg(CheckEvent)
                            - WaitForSingleObject(Event1, 10 sec)

OnMsg()
{
  WaitForSingleObject(Event1, 0 sec)
    - сразу reset
}
                             - если не сработало - перезапуск теста
                             - killTimer ; startTimer
« Последнее редактирование: 22-04-2010 16:21 от Malaja » Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 22-04-2010 16:24 » 

Тут система такая.  Есть 2 процесса: 1. следящий процесс (он же watchdog)  2. отслеживаемый процесс
(1) просто запускает таймер. Если этот таймер сработал, значит (2) завис. (2) через какой-то период времени сбрасывает этот таймер, чтоб показать что он не умер. На самом деле (2) может, например, посылать команду (1) (событие вполне подходит), и (1) уже сбрасывает свой таймер.

Ну т.е. набор функций совершенно правильный.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 22-04-2010 16:28 » 

Это проще показать на аппаратном уровне

Отдельный девайс = watchdog
Инициализация его - задать время его работы.

Далее идет основной цикл программы
В этом цикле watchdog, а вернее таймер, перезапускается.

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


Как это реализовать программно?

Устанавливаешь таймер.

Заходишь в основной цикл, из цикла запускаешь свои процессы.
Если алгоритм линейный, то вроде все понятно.
А если параллельно запускаются процессы, или процесс достаточно длителен, то каждый процесс дает сигнал собаке что он жив.
Как это должно происходить - не знаю. Обменивайся сигналами, или как-то по другому.
Соответственно, видимо,  собака должна "считать" количество выходящих и входящих, возможно также и знать о приблизительном времени выполнения каждого процесса.

Структура {
proccess1:id,time;
proccess2:id,time;
.....
}

while true {
Истекло(proccess1.time) ? kill(proccessid) : continue
и так далее
}
Это просто, наверное.

Сложнее когда не знаешь времени работы процесса.

Запуск собаки
Запуск процессов и регистрация
while  true {
Жив(proccess[id]) ? continue : kill
}

Вот это жив должен анализировать время работы процесса. если он превысил, то килять его.


ps Это все без теории...
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 22-04-2010 16:30 » 

Malaja, давай без всех этих привязок к языку.
Формально алгоритм понятен?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #11 : 22-04-2010 17:21 » 

Слав,
да какая привязка - просто я сначала указала язык, т.к. думала, что у кого-то есть примерчик.
В любом случае всем спасибо за помощь и терпение!

Насчет алгоритма - я вижу это так:

Код:
ctor_MainProc()
{
   startWatchDogProcess( WatchDogFunc );

   timerMain = startTimer(15 sec);
}

OnTimer()
{
  if (timerID == timerMain)
  {
    SetEvent(Watchdog_Event); // teper' on svoboden
  }
  else if (timerID == timerWatchdog)
  {
     restartMainProc(); // раз тест висит, с этим надо что-то делать
     killTimer(timerWatchdog);
     startTimer(timerWatchdog);
  }

}


WatchDogFunc()
{
  Watchdog_Event = CreateEvent(занято);
  timerWatchdog = startTimer(30 sec);

  while()
  {
    WaitForSingleObject(Watchdog_Event, 15 sec);
    If(OK)
    {
      Watchdog_Event = ResetEvent(занято); // или это происходит автоматически при manualFlag = false
      killTimer(timerWatchdog);
      startTimer(timerWatchdog);
    }
  }
}


Так? Или я опять что-то не понимаю?
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 22-04-2010 17:31 » 

Ирин, пусть главный процесс (сложный и подверженный глюкам) запускает простой до офигения процессик WatchDogProcess.
Пусть главный процесс в некоем цикле постоянно взводит событие (и это должно происходить, скажем, не реже, чем раз в 10 секунд).

WatchDogProcess делает очень простую вещь:

1) проверяет, взведено ли событие
   - если да, то сбрасывает в 0.
   - если нет, то проверяет время простОя. Если время превысило таймаут - то мочит и перезапускает главный процесс
2) переход к пункту 1
Записан

Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #13 : 22-04-2010 17:35 » 

Леш, так вроде бы я именно это и нарисовала... Или нет?
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 22-04-2010 17:38 » 

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

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 22-04-2010 17:39 » 

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

Но можно и watchdog сделать активным.
т.е. как топливо в двигателе.
Есть топливо - работает, нет умираем.

Кстати, http://khpi-iip.mipk.kharkiv.edu/library/extent/os/qnx/qnx_3.html
тут и теория и реализация

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #16 : 22-04-2010 17:44 » 

без соблюдения синтаксиса, я мыслю вот как-то так:
Код:
//главный процесс
ctor_MainProc()
{
   startWatchDogProcess( WatchDogFunc );
}

feedbackFunc()
{
   SetEvent(Watchdog_Event);//я жив!!
}

TestFunc(feedbackFunc)
{
  for(;;)
  {
    feedbackFunc();
    ...
    ...
  }
}

//----------------------------
//ватчдог
WatchDogFunc()
{
  while()
  {
    If(событие_установлено_?_ожидаем_это_15_секунд)
    {
       процесс жив

       сбросить событие
    }
    else
    {
       перезапустить главный процесс
    }
  }
}


« Последнее редактирование: 22-04-2010 17:57 от Алексей1153++ » Записан

Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #17 : 22-04-2010 17:48 » 

Леш, какой на фиг шарп! Обычный родной с++ в полуструктурном виде! Ага
Т.е. названия функций верны (за исключением больших-маленьких буквочек), а параметры - нет Ага
А как ты без таймера сделаешь:
Цитата
Пусть главный процесс в некоем цикле постоянно взводит событие (и это должно происходить, скажем, не реже, чем раз в 10 секунд).

О! Пока писала тебе ответ, появился код.
Теперь поняла, как ты без таймера хочешь обойтись. Но подозреваю, что это будет стоить много времени, т.к. постоянно будет идти проверка в цикле.
Надо будет попробовать оба варианта.

///////////

Слав, так я его вроде как пассивным и сделала - сратую как процесс из основного теста...  Здесь была моя ладья...
Спасибочки за ссылку! Мне в процессе поиска сегодня она не попадалась - не захотел меня родной политех порадовать   Жаль

Еще раз всем огромное спасибо!
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 22-04-2010 17:50 » 

Алексей1153++, по логике будет правильно если следящий процесс, содержащий "псину", будет запускать другие процессы. Как-то расточительно по отдельному процессу-"псу" на каждый отслеживаемый процесс.
С другой стороны, отдельный watchdog на каждый процесс это конечно проще (гораздо проще) в реализации.

В коде поста #11, я как-то не понял, зачем нужен timerMain.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 22-04-2010 17:53 » 

Не, процессор кушать ватчдог не будет, если влепить Sleep(100) - там даже 1 уже будет почти незаметно с точки зрения нагрузки на процессор

    If(событие_установлено_?_ожидаем_это_15_секунд)
    {
       процесс жив
       Sleep(100);
    }
    else
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 22-04-2010 17:58 » 

resource, мне не жалко по собаке на процесс, если, особенно, процессов немного - один Улыбаюсь

кстати, я забыл сбросить событие - дописал в пост №16
Записан

resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 22-04-2010 17:59 » 

Ну если один, то понятно. А если 10 или 20? С "собаками" это 20 и 40 соответственно.

А кто кого запускает это без разницы. Просто для меня логичнее, когда следящий процесс запускает отслеживаемый
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 22-04-2010 18:05 » 

resource, легко - один собак и 20-40 событий. Только нужно будет немного иначе ожидание организовать:

Код:
WatchDogFunc()
{
while()
{

for(int i=0;i<количество процессов;i++)
{
If(событие_i_установлено_?)//проверяем без ожидания
{
процесс_i жив
сбросить событие_i
}
else
{
перезапустить процесс_i
}
Sleep(1000);
}
}
}

если наличие Sleep сказывается на гибкости, можно переписать с применением GetTickCount
Записан

resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 22-04-2010 18:13 » 

С алгоритмической точки зрения - да, легко. Но я конечно не пытаюсь сказать, что это дико сложная задача Улыбаюсь но алгоритм действительно выглядит попроще чем сам код.

ЗЫ  Задержки (Sleep) не знаю зачем вообще нужны
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #24 : 22-04-2010 18:17 » 

ЗЫ  Задержки (Sleep) не знаю зачем вообще нужны

запусти бесконечный цикл без слипа - поймёшь, зачем Улыбаюсь
Записан

resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 22-04-2010 18:23 » 

Ну серьезно, что будет?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #26 : 22-04-2010 18:28 » 

ну, 100% загрузка процессора, а так ничего страшного ))
Записан

resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 22-04-2010 18:35 » 

 Не понял  от чего это 100% загрузка? от инкремента и вызова WaitForMultipleObjects ? Ну если задать потоку огромный приоритет.... и то.....
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #28 : 22-04-2010 18:46 » 

msdn под рукой нет, чем проверяются события не помню (  - а проверять надо тут без ожидания события

Но в любом случае, я без слипа не запускал бы так ватчдог
Записан

resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 22-04-2010 18:56 » 

msdn под рукой нет, чем проверяются события не помню

WaitForMultipleObjects и проверяются. И почему обязательно без ожидания? Можешь ожидать там как раз столько, сколько и в Sleep ждал. Можешь и больше.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #30 : 23-04-2010 02:52 » 

resource, с ожиданием - это подходит для случая с 1 контролируемым процессом. А если их 20-40 , то долговато ждать будет Улыбаюсь
Записан

zubr
Гость
« Ответ #31 : 23-04-2010 04:05 » 

resource, с ожиданием - это подходит для случая с 1 контролируемым процессом. А если их 20-40 , то долговато ждать будет Улыбаюсь
Так для этого и применяется WaitForMultipleObjects, в отличие от WaitForSingleObject.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #32 : 23-04-2010 04:09 » 

zubr, теперь понятно ) Там же список хендлов можно, оказывается

DWORD WINAPI WaitForMultipleObjects(
  __in  DWORD nCount,
  __in  const HANDLE* lpHandles,
  __in  BOOL bWaitAll,
  __in  DWORD dwMilliseconds
);
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #33 : 23-04-2010 04:29 » 

Слав,
ну и где они, твои 25 лет? А заодно и мои тоже?  Улыбаюсь)

Ага, видимо, программный (т.е. с железом ничего общего не имеет).
Суть задачки:
Есть тест, который для своей работы стартует парочку других ехе-шников (как процессы). Так вот иногда один из этих процессов зависает, что приводит к общему зависанию теста.
Появилась идея написать эту самую собаку, которая следила бы за тестом и в случае зависания давала бы команду "убить Билла" Ага , т.е. killProcess.

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

как это делается у нас?
а делается это так: софтина timeoutrun (самописная тулза) получает в качестве параметров команду (фактически кусок командной строки со всеми параметрами) и timeout в течении которого должна выполнятся команда
далее она поднимает всё, что указано в параметре (просто через cmd) и запоминает id поднятого процесса
затем ждёт или завершения процесса или истечения timeout
если, что грохает всё дерево процессов

Что касается WD (WatchDog)
Примерно такой-же принцип можно использовать для построения WD
Но WD это WD и слежение за наличием процесса не единственный способ его построить и не всегда правильный
А запуск и ожидание TimeOut это другая задача, гораздо более простая
Записан

Странно всё это....
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #34 : 23-04-2010 05:44 » 

очень давно реализовали такую штукенцию.
Система тестов.
Каждый тест что-то свое делал.
Все тесты запускались из одной оболочки.
Каждому тесту было выделено поле для своего обнаружения.
Каждый тест писал свое состояние (например шаг 1, шаг 2 и т.д.)
Каждый шаг теста нормировался по времени.

На каждое поле было повешено событие onchange.
при возникновении события WD сбрасывал состояние ожидание.

Таймер регулярно взводил флаг ожидания процесса, в соответствии с его временными характеристиками.

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

В случае зависания процесса (теста) - тест килялся.

зы написано это было на Tk/Tcl
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #35 : 23-04-2010 09:00 » 

1) resource:
В коде поста #11 timerMain - был встроен для того, чтобы раз в 15 секунд менять состояние event-а (т.о. говоря watchdog-у, что мы еще живы)
2) Леш,
я вместо Sleep() использовала timeout-параметр в функции WaitForSingleObject()
3) Слав, прости за тупость, но что имеется в виду под

Таймер регулярно взводил флаг ожидания процесса, в соответствии с его временными характеристиками.

(просто я уже все эти вещи учила по-немецки или по-английски, поэтому некоторые понятия мне неясны... Возвести флаг - означает поставить его в nonsignaled или в signaled?)

Так?
SetTimer(timeout);
SetEvent(hEvent);

4) LogRus, спасибо за идею! Сейчас посмотрю, смогу ли я ее применить, упростив себе т.о. жизнь.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #36 : 23-04-2010 09:41 » 

Система была построена приблизительно так
Тест1
  Шаг1 Время1
  Шаг2 Время2
Тест2
  Шаг1 Время1
  Шаг2 Время2
  Шаг3 Время3
  Шаг4 Время4

WD init
  Запуск Тест1 Запомнить->Тест1.Шаг1.Время1
  Запуск Тест2 Запомнить->Тест2.Шаг1.Время1

WD job
  Анализ->Тест1.Шаг1.Время1 ? (истекло) kill : (не истекло) wd.state1 = состояние_ожидание_шага
  ...

Тест1 в работе регулярно устанавливает свое состояние, соответствующее шагу  (например: шаг1 имеет два состояния 0 и 1, шаг2 - 2 и 3)
И т.д.


зы. Под это была накручена научная работа, которая, к сожалению, кандидатской не закончилась Жаль
Имелись публикации и прочее. Где их искать даже не знаю... "Все пропало ..."


Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #37 : 23-04-2010 13:05 » 

Ткните меня носом, где я сошла с ума...
Сделала тестовую программку на c++ в студии 2008: цоздала консольное приложение, попыталась потестировать собаку...
В результате уперлась в то, что не могу простестировать, т.к. у меня не срабатывает таймер Не может быть...  С ума сойти...  Где поп, а где приход... Такого я еще не видела... И в чем дело - никак не пойму!

* DiffTests_console.zip (5.27 Кб - загружено 775 раз.)
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #38 : 23-04-2010 14:27 » 

Malaja, не понял, зачем так сложно...

Вот совсем простой пример - без дополнительных таймеров.
Код: (Text)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

// Таймаут проверки завершения очередного действия.
#define TIMEOUT 10000

// Событие завершения очередного действия процесса.
HANDLE processFinishActionEvent;

// Наблюдаемый процесс
void process()
{
        // Процесс работает бесконечно.
        for(;;)
        {
                // Процесс выполняет какое-то действие, что занимает случайное время.
                printf("PROCESS: Start action.\n");
                ::Sleep(rand() % (TIMEOUT * 2)); // Пусть время в худшем случае в 2 раза превышает таймаут.
                printf("PROCESS: Finish action.\n");
                // После этого он устанавливает событие о том, что действие завершил.
                ::SetEvent(processFinishActionEvent);
        }
}

// Наблюдающий процесс
DWORD WINAPI watchDog(LPVOID lpParameter)
{
        // Процесс работает бесконечно.
        for(;;)
        {
                printf("WATCHDOG: Wait the next action.\n");
                // Ждёт события в течение таймаута.
                switch(::WaitForSingleObject(processFinishActionEvent, TIMEOUT))
                {              
                case WAIT_OBJECT_0:
                        // Дождался события, значит наблюдаемый процесс жив.
                        // Сбрасывает событие и ждёт следующего.
                        printf("WATCHDOG: Action was finished - OK.\n");
                        ::ResetEvent(processFinishActionEvent);
                        break;
                case WAIT_TIMEOUT:
                        // Не дождался события за отведённое время, значит наблюдаемый процесс завис.
                        // Завершает наблюдаемый процесс.
                        printf("WATCHDOG: Action is too long - FAIL.\n");
                        printf("WATCHDOG: Terminate process.\n");
                        ::ExitProcess(0);
                        break;
                }
        }
}

// Основная программа.
int main()
{
        srand(time(NULL));
        // В начале событие завершения очередного действия процесса установлено,
        // будто до этого успешно завершилось очередное действие.
        processFinishActionEvent = ::CreateEvent(NULL, TRUE, TRUE, NULL);
        // Запускаем наблюдающий процесс.
        ::CreateThread(NULL, 0, &watchDog, NULL, 0, NULL);
        // Запускаем наблюдаемый процесс.
        process();
        return 0;
}
Что касается таймеров, то функция SetTimer предписывает Windows спустя указанное время послать процессу сообщение WM_TIMER. Но чтобы его обработать, по-моему приложение должно быть для подсистемы Windows, а не Console, с WinMain и т.д.
« Последнее редактирование: 23-04-2010 20:36 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #39 : 23-04-2010 14:51 » 

Подсистема к делу не относится. С SetTimer ничего не получится. Чтобы получить сообщение таймера WM_TIMER, нужно, чтобы наблюдаемый процесс периодически вызывал PeekMessage - функцию получения системных сообщений. Очевидно, что делать это он может лишь в перерывах между какими-то внутренними действиями - т.е. в моём примере функция process выглядела бы как:
Код: (Text)
// Наблюдаемый процесс
void process()
{
        // Процесс работает бесконечно.
        for(;;)
        {
                // Процесс выполняет какое-то действие, что занимает случайное время.
                printf("PROCESS: Start action.\n");
                ::Sleep(rand() % (TIMEOUT * 2)); // Пусть время в худшем случае в 2 раза превышает таймаут.
                printf("PROCESS: Finish action.\n");
                // После этого он получает все накопившиеся события.
                MSG msg;
                while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0)
                {
                        switch(msg.message)
                        {
                        case WM_TIMER:
                                // Если было событие таймера, сигнализирует о том, что действие завершил.
                                ::SetEvent(processFinishActionEvent);
                                break;
                        }
                }
        }
}
Только это бессмысленное усложнение.

Асинхронные таймеры тоже ничего не дадут, поскольку за их запуск будет отвечать операционная система или другой поток, и они будут исправно срабатывать вне зависимости от состояния активного процесса - последний может благополучно зависнуть, и никто об этом не узнает.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #40 : 23-04-2010 15:04 » 

Дим,
1) так я же поэтому и установила свою собственную функцию для таймера и не задала hwnd, чтобы не зависеть от WM_TIMER!
Теоретически я устанавливаю таймер на определенное время, после истечения которого и вызывается либо WinProc (если про создании таймера не указана собственная процедура и указан hwnd окна - тогда ему будет послан WM_TIMER) либо та самая своя процедура.
Или?

2) за идею спасибо! кажется, я перемудрила с таймерами - просто хотела иметь контроль над процессом постоянно.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #41 : 23-04-2010 16:23 » 

Цитата: Malaja
1) так я же поэтому и установила свою собственную функцию для таймера и не задала hwnd, чтобы не зависеть от WM_TIMER!
Теоретически я устанавливаю таймер на определенное время, после истечения которого и вызывается либо WinProc (если про создании таймера не указана собственная процедура и указан hwnd окна - тогда ему будет послан WM_TIMER) либо та самая своя процедура.
Или?
Всё же или
Цитата: MSDN
Handle to the window to be associated with the timer. This window must be owned by the calling thread. If this parameter is NULL, no window is associated with the timer and the nIDEvent parameter is ignored.
Отсутствие hwnd всего лишь означает, что таймер не привязан к какому-то окну процесса. Это не позволяет использовать nIDEvent, но в данном случае это и не нужно.

Цитата: MSDN
An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.
Наличие адреса обработчика означает, что не нужно вручную писать case WM_TIMER в цикле обработки, НО при этом должна вызываться функция обработки сообщения по умолчанию DefWindowProc. В твоей программе она не используется - поэтому таймер не срабатывал. Таймер не является асинхронным - его обработчик выполняется в том же потоке, в котором таймер был установлен. Срабатывание возможно организовать только при получении потоком сообщений от системы. Это значит, что поток должен периодически проверять сообщения системы - т.е. нельзя запустить долго исполняющиеся вычисления, поток должен время от времени (и лучше регулярно) возвращаться к циклу обработки системных сообщений.
« Последнее редактирование: 23-04-2010 16:35 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #42 : 23-04-2010 17:18 » 

Дим,
спасибо! Я привыкла, что таймер у меня всегда работал... Но при этом забыла, что тут нет мфц, у которого всегда внутри есть обработчик событий...
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #43 : 26-04-2010 14:04 » 

Маленькое замечание по поводу таймера в основном thread-е (как раз сейчас попробовала): он не спасает, т.е. он работает вне зависимости от того, висит ли thread или нет.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #44 : 26-04-2010 15:08 » 

Malaja, я об этом и сказал
Цитата: dimka
Асинхронные таймеры тоже ничего не дадут, поскольку за их запуск будет отвечать операционная система или другой поток, и они будут исправно срабатывать вне зависимости от состояния активного процесса - последний может благополучно зависнуть, и никто об этом не узнает.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #45 : 27-04-2010 02:35 » 

По моему, что-то у вас всё слишком сложно получается
Почему бы не создать внешний watchdog который просто ждёт N секунд до завершения процесса, какая разница в какой именно точке повис тест, важно, что он повис. (потом можно логи почитать для анализа)
Главный бонус, что не надо модифицировать тесты для работы с таким WD
Записан

Странно всё это....
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #46 : 27-04-2010 05:25 » 

LogRus, согласен. Правда в тесте всё равно конечно должен быть код, связанный с wd, но код этот должен быть минимальным, просто чтоб сигналить, что процесс еще живой.
 Однако, чтобы не заморачиваться очередью сообщений в тесте (ну если она там уже обрабатывается, то и проблемы нет), придется пользоваться любыми функциями времени (хоть GetTickCount). Это конечно грубовато, но поскольку речь идет о секундах, а не о миллисекундах, то вполне подойдет.
 В самом wd, лучше наверное обрабатывать сообщения. Окно ведь для этого необязательно.
Записан
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #47 : 27-04-2010 08:16 » 

Дим,
у меня, видимо, что-то в голове заклинило на таймере... Я явно "в пылу борьбы" невнимательно прочла это сообщение и решила, что раз я запустила таймер не в отдельном треде, а в том же самом, то все будет хорошо.

LogRus, resource:
идея была в следующем - отслеживать не только целый тест (а их там > 100), а и внутри теста проводить контрольные выстрелы (т.е. в процессе выполнения всего цикла тестов каждые n-секунд проверять приложение на предмет наличия жизни).
С другой стороны, не хотелось ничего особо модифицировать, а изменения сделать очень компактными (почему я и схватилась за таймер - написал себе процедуру для него и все!).
Короче, хотелось красивых решений Ага
Но из этого ничего не вышло - придется таки в wachdog-е просто устанавливать контрольное время исходя из самого длинного теста, выполняемого на самой медленной машине...
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #48 : 27-04-2010 09:33 » 

Malaja, неправильно ты дядя Федор бутерброд кушаешь.

Я про время тестов...
Нужен контрольный тест времени и от него все времена пересчитывать.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #49 : 27-04-2010 10:12 » 

Слав,
что ты имеешь в виду?
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #50 : 27-04-2010 11:00 » 

запускаешь тест времени на Любой машине и запоминаешь
Потом запускаешь его на другой и получаешь время выполнения теста.
Рассчитываешь коэф. и применяешь его (коэф) ко всем тестам

Тест времени на контрольной машине = 10
Время test1 =30

Тест времени на тестируемой 20
коэф = 2
Время test1 на тестируемой 30*2


Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #51 : 27-04-2010 11:11 » 

LogRus, согласен. Правда в тесте всё равно конечно должен быть код, связанный с wd, но код этот должен быть минимальным, просто чтоб сигналить, что процесс еще живой.

Зачем? Улыбаюсь сказано тест должен завершиться за 2 минуты, не завершился, значит рубим, он или завис или тормозит или не корректный таймаут под конкретный тест.
Из опыта: у нас тысячи тестов и пока ни один понятия не имеет, что его запускают из WD.

LogRus, resource:
идея была в следующем - отслеживать не только целый тест (а их там > 100), а и внутри теста проводить контрольные выстрелы (т.е. в процессе выполнения всего цикла тестов каждые n-секунд проверять приложение на предмет наличия жизни).
Какая цель теста? Найти проблему, если тест не выполнился за N секунд значит он провален, задача достигнута, разработчик получает письмо о проваленном тесте с логами теста в атаче и начинает разбираться.

.................
Короче, хотелось красивых решений Ага
.................
так это и есть красивое решение Улыбаюсь просто и красиво, а главное дёшево

тест зациклился, но что-то делает и что-то пишет в лог:
как понять, что он зациклился?
а если цикл не просто for, а сложный каскад обработки сообщений?
Записан

Странно всё это....
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #52 : 27-04-2010 11:17 » 

запускаешь тест времени на Любой машине и запоминаешь
Потом запускаешь его на другой и получаешь время выполнения теста.
Рассчитываешь коэф. и применяешь его (коэф) ко всем тестам

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

тесты производительности это отдельная песня
Записан

Странно всё это....
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #53 : 27-04-2010 11:33 » 

LogRus, конечно про настройки теста и идет речь. Какие дефолтные значения могут приниматься - зависит от разработчиков.

Тесты могут гоняться на разных по мощности машинах, соответственно, разное время выполнения.

Временной тест - это часть самодиагностики. будет она реализована в отдельном тесте или зашита в сам WD, не суть важно. Важно его наличие.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #54 : 27-04-2010 12:20 » 

Слав,
спасибо - теперь поняла! Именно это я и хотела сделать, но для простоты (ибо тестовых машин у нас 7 штук) сделать измерения на одной и волевым решением ввести коэффициент = 2, т.к. машины не могут настолько уж различаться в быстродействии.
 
LogRus,

Цитата
Какая цель теста? Найти проблему, если тест не выполнился за N секунд значит он провален, задача достигнута, разработчик получает письмо о проваленном тесте с логами теста в атаче и начинает разбираться.

Ты прав на все 100 - это я перемудрила. Скромно так... В принципе, если тест где-то завис, то это уже найденная проблема, а что конкретно не так - головная боль разработчика.  Отлично

Еще раз всем огромное спасибо за терпение и объяснения!
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #55 : 27-04-2010 13:44 » 

LogRus, понял. Согласен.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #56 : 28-04-2010 03:37 » 

Опыт Улыбаюсь
Записан

Странно всё это....
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #57 : 03-05-2010 11:58 » 

Небольшое дополнение к теме:
если нужен watchdog для использования его затем в NUnit-тесте, то тут возникают шероховатости:
в обычной жизни NUnit сам запускает тесты по очереди, что позволяет им находиться в основном треде и посылать сообщения об ошибках непосредственно самому NUnit-у, который, в свою очередь, имеет возможность реагировать в соответствии с обстановкой (т.е. в случае Assert-ов просто прекращать тест).
При использовании watchdog-а ситуация меняется: теперь watchdog оказывается в основном треде, а тесты - в дополнительном, который запускает наш watchdog.
При этом возникает проблема передачи сообщений от теста оболочке NUnit.
Для разруливания надо создать какой-нибудь свой класс, который будет в случае возникновения ошибок их либо накапливать, дабы по окончании теста выдать в лог (если речь идет о некритических ошибках), либо прерывать тест, а затем прописать всю инфу по ошибкам в наш лог.

Я сделала для себя пример, дабы убедиться в том, что идея правильная и будет работать. НУ а затем решила его для всех выложить (вдруг кому-то еще пригодится).
Если вы считаете, что это никому не надо - удаляйте.

* NunitTest.zip (11.62 Кб - загружено 749 раз.)
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #58 : 03-05-2010 13:16 » 

Удалять ничего не надо имхо. 11 кило жрать не просят, а нормальных исходников не так много выкладывается
Записан
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #59 : 03-05-2010 14:36 » 

Забыла дописать (предупредитъ)!
Дело в том, что 1:1 это тоже исполъзовать не выйдет - все равно надо делать какие-то поправки с учетом конкретной реализации (у каждого свое построение теста, необходимые действия на старте и в конце, ну и т.д.), поэтому это, к сожалению,  не 100%-ный рецепт, который можно пустить в дело не глядя и не разбирая.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines