snedelko 0 20 января, 2007 Опубликовано 20 января, 2007 · Жалоба Ситуация следующая: есть процесс, который запускается по автозапуску системы. Проблема: процесс при неизвесных обстоятельствах вылетает. Причины: разные java script:emoticon(':)', 'smid_2'). Возможно это утечка памяти, аппаратный сбой (программа работает с драйверами устройств), ошибка при работе с памятью и т. д. Мне нужно отследить "вылетание", и заново запустить программу. Я решил сделать это при помощи скрипта (см. влож. файл), который я поместил в автозапуск (вместо самой программы). Скрипт простой (напомню, что pidof - команда, которая возвращает pid процесса по имени, и если процесса нет, возвращает 0). Все работает, когда программы выходит по exit(0). Но вот при segmentation fault скрипт не помогает, так как процесс становиться зомби (т.е. имеет pid != 0). Подскажите почему, или предложите свой вариант. smobi.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
InvisibleFed 0 21 января, 2007 Опубликовано 21 января, 2007 · Жалоба Известное мне определение процесса зомби - процесс не имеющий родителя (в случае, когда родител мертв, а потомок остался жив). Может посмотреть, жив ли родитель процесса? Если мертв - значит твой процесс - зомби. Кажды процесс, насколько я помню хранит pid родителя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olej 0 21 января, 2007 Опубликовано 21 января, 2007 · Жалоба Известное мне определение процесса зомби - процесс не имеющий родителя (в случае, когда родител мертв, а потомок остался жив). Может посмотреть, жив ли родитель процесса? Если мертв - значит твой процесс - зомби. Почти так да не совсем: - зомби - это всегда завершившийся процесс (а не завершившийся родитель) ... - процесс становится зомби, когда он отправляет по завершению SIGCHLD - а его некому обработать, например процесс родитель просто не обрабатывает его, например, не ожидает завершения на wait() или waitpid().... - ... можете в запускающем процессе просто добавить пустой обработчик SIGCHLD ;) ... Кажды процесс, насколько я помню хранит pid родителя. pid_t getppid( void ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
snedelko 0 22 января, 2007 Опубликовано 22 января, 2007 · Жалоба Вообще, с процессами зомби немного знаком - боролся я с ними, вызывая в обработчике SIGCHLD функцию wait(). В моей ситуации родителем кто является? Скрипт? Объясните пожалуйста. Если скрипт - то есть ли команда - аналог функции wait()? И подскажите мне вот в чем: мой скрипт срабатывает около 3-х раз (в ситуации, когда программа завершается сама (по exit)), а на 4-й раз появляются зомби. Откуда? И почему не появлялись раньше? А вот когда программа завершается по segmentation fault (то бишь её рубит Линукс, тем же kill наверно), то зомби появляються СРАЗУ.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olej 0 22 января, 2007 Опубликовано 22 января, 2007 · Жалоба Вообще, с процессами зомби немного знаком - боролся я с ними, вызывая в обработчике SIGCHLD функцию wait(). В моей ситуации родителем кто является? Скрипт? Объясните пожалуйста. Если скрипт - то есть ли команда - аналог функции wait()? И подскажите мне вот в чем: мой скрипт срабатывает около 3-х раз (в ситуации, когда программа завершается сама (по exit)), а на 4-й раз появляются зомби. Откуда? И почему не появлялись раньше? А вот когда программа завершается по segmentation fault (то бишь её рубит Линукс, тем же kill наверно), то зомби появляються СРАЗУ.... Я мало что понял из этого объяснения :(... Скрипт не может быть родителем ;) - родителем может быть только породивший процесс, это может быть, например, скриптовый интерпретатор, выполняющий ваш скрипт... P.S. предложение-подсказка - как разобраться в вашей trouble: - сделайте над своим процессом пустую "обёртку", которая будет только exec/spawn ваш процесс... - в ней вы можете перехватывать - наблюдать - обрабатывать все события... - разобравшись что происходит - выбросите обёртку ;). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
InvisibleFed 0 23 января, 2007 Опубликовано 23 января, 2007 · Жалоба - зомби - это всегда завершившийся процесс (а не завершившийся родитель) ... - процесс становится зомби, когда он отправляет по завершению SIGCHLD - а его некому обработать, например процесс родитель просто не обрабатывает его, например, не ожидает завершения на wait() или waitpid().... А если процесс еще не завершился, а родитель уже откинулся - как ни крути, а процесс уже по любому зомби (его просто некому будет убить по завершению). Если родитель еще жив и по каким-то причинам не может обработать SIGCHLD - процесс не может считаться зомби, т. к. потенциально родитель еще может его кончить. Интересно, что произойдет с родителем, если он не будет "ждать детей" (wait, waitpid) - он просто заврешиться и все потомки станут зомби. Тонкости, конечно, но все что изложил Olej умещается в моем определении зомби. Или существет пример, когда оно неверно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
snedelko 0 23 января, 2007 Опубликовано 23 января, 2007 · Жалоба А если процесс зомби, то потоки, запущенные им, тоже зомби? И вообще, тонкостей тут куча, где бы про это подробно почитать ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
niid 0 23 января, 2007 Опубликовано 23 января, 2007 · Жалоба А если процесс зомби, то потоки, запущенные им, тоже зомби? И вообще, тонкостей тут куча, где бы про это подробно почитать ? Вот: Если же потомок уже завершил работу, а предок не готов принять от системы сигнал об этом событии, то потомок не исчезает полностью, а превращается в "зомби" (zombie) Процесс зомби, следовательно завершил работу и не может принимать сигналы. Потомки станут зомби, когда завершат свою работу. Вот Вам еще несколько цитат: Если родительский процесс по какой-то причине завершится раньше дочернего, последний становится "сиротой" (orphaned process). "Сироты" автоматически "усыновляются" программой init, выполняющейся в процессе с номером 1, которая и принимает сигнал об их завершении. Если же потомок уже завершил работу, а предок не готов принять от системы сигнал об этом событии, то потомок не исчезает полностью, а превращается в "зомби" (zombie); в поле Stat такие процессы помечаются буквой Z. Зомби не занимает процессорного времени, но строка в таблице процессов остается, и соответствующие структуры ядра не освобождаются. После завершения родительского процесса "осиротевший" зомби на короткое время также становится потомком init, после чего уже "окончательно умирает". Последнее из состояний процесса, достижимых внутренней синхронизацией, есть состояние промежуточного завершения текущего процесса - SZOMB (состояние "зомби"). Состояние "зомби" имеет место, если процесс-потомок завершается по системному вызову exit или по сигналу до планируемой реализации системного вызова wait в процессе-предке. При этом образ завершившегося процесса освобождает адресное пространство, но его дескриптор временно сохраняется в таблице процессов, чтобы обеспечить корректную обработку системного вызова wait в процессе-предке. В состоянии "зомби" процесс не имеет образа в RAM, но информация о нем сохраняется в таблице процессов. Он не поедает ресурсы, но теоретически могут кончится PID'ы. Напрямую зомби не убить, нужно уничтожить родительский процесс, тогда зомби умрет вместе с ним. Если есть желание, можете почитать про организацию процессов: http://cad.narod.ru/methods/os_unix/unibas/process.html http://linux-admin.net.ru/content/257 А вообще, можете поискать в Google-Linux. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olej 0 24 января, 2007 Опубликовано 24 января, 2007 · Жалоба А если процесс зомби, то потоки, запущенные им, тоже зомби? И вообще, тонкостей тут куча, где бы про это подробно почитать ? Вопрос в общих контурах - понятный и описанный, а в деталях - заинтересовал... Я тут набросал тест маленький, на скорую руку, который позволяет создавать "временных зомби", наблюдать их... (пример очень draft - писался на коленке - no comments): #include <signal.h> #include <iostream> using std::cout; using std::endl; using std::flush; static const int MSG_BUF = 160; static char msgbuf[ MSG_BUF ]; static char *puthead( void ) { struct timespec t; clock_gettime( CLOCK_REALTIME, &t ); int sec = t.tv_sec % 60, min = t.tv_sec % 3600 / 60, ms = t.tv_nsec / 1000000, mks = t.tv_nsec % 1000000 / 1000; sprintf( msgbuf, "[%02d:%02d.%03d.%03d] %d: ", min, sec, ms, mks, getpid() ); return msgbuf + strlen( msgbuf ); }; static void chend( int ) { sprintf( puthead(), "oh, my God - my child is dead!\n" ); cout << msgbuf << flush; }; int main( int argc, char* argv[] ) { int c, msec = 300, level = 0; while( ( c = getopt( argc, argv, "c:t:" ) ) != -1 ) { switch( c ) { case 'c': level = atoi( optarg ); break; case 't': msec = atoi( optarg ); break; default : exit( EXIT_FAILURE ); }; }; signal( SIGCHLD, chend ); pid_t id; // = -1; int w = 4, j = -1; while( --level > 0 && ( id = fork() ) == 0 ) { w += j; j = ( j < 0 ? 2 : -1 ); }; sprintf( puthead(), "start - my parent is %d\n", getppid() ); cout << msgbuf << flush; for( int i = 0; i < w; i++ ) if( delay( msec ) != 0 ) --i; else { sprintf( puthead(), "continue %d - parent is %d\n", i + 1 , getppid() ); cout << msgbuf << flush; }; sprintf( puthead(), "finished\n" ); cout << msgbuf << flush; exit( EXIT_SUCCESS ); }; а вот вариант его прогона: # ./zomby2 -c4 -t2000 [38:04.744.723] 6467647: start - my parent is 4710443 [38:04.746.723] 6471744: start - my parent is 6467647 [38:04.748.722] 6471745: start - my parent is 6471744 [38:04.748.722] 6471746: start - my parent is 6471745 [38:06.746.417] 6467647: continue 1 - parent is 4710443 [38:06.748.416] 6471744: continue 1 - parent is 6467647 [38:06.750.416] 6471745: continue 1 - parent is 6471744 [38:06.750.416] 6471746: continue 1 - parent is 6471745 [38:08.748.110] 6467647: continue 2 - parent is 4710443 [38:08.750.110] 6471744: continue 2 - parent is 6467647 [38:08.752.110] 6471745: continue 2 - parent is 6471744 [38:08.752.110] 6471746: continue 2 - parent is 6471745 [38:10.749.804] 6467647: continue 3 - parent is 4710443 [38:10.751.804] 6471744: continue 3 - parent is 6467647 [38:10.751.804] 6471744: finished [38:10.752.804] 6467647: oh, my God - my child is dead! [38:10.753.804] 6471745: continue 3 - parent is 6471744 [38:10.753.804] 6471746: continue 3 - parent is 6471745 [38:12.754.497] 6467647: continue 4 - parent is 4710443 [38:12.754.497] 6467647: finished [38:12.755.497] 6471745: continue 4 - parent is 6471744 [38:12.755.497] 6471746: continue 4 - parent is 6471745 [38:12.755.497] 6471746: finished [38:12.756.497] 6471745: oh, my God - my child is dead! # [38:14.758.191] 6471745: continue 5 - parent is 1 [38:14.758.191] 6471745: finished # # pidin 6467647 1 ./zomby2 10o NANOSLEEP 6471744 (Zombie) 6471745 1 ./zomby2 10o NANOSLEEP 6471746 1 ./zomby2 10o NANOSLEEP - проганял я, естественно ;), не в Linux - но он весь - POSIX: вы можете взять и поганять нечто подобное в вашей любимой ОС - он создаёт любое число процессов, каждый из которых может поочерёдно становиться зомби. P.S. мне особенно понравился ;) цикл: while( --level > 0 && ( id = fork() ) == 0 ) { w += j; j = ( j < 0 ? 2 : -1 ); }; - который циклом и не является ("... не верь глазам своим"(с) К.Прутков), и в каждом процессе выполняется по 1-й итерации этого "якобы цикла" ровно по 1-му разу : "цикл между процессами" ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
akivas 0 29 января, 2007 Опубликовано 29 января, 2007 · Жалоба Вообще, с процессами зомби немного знаком - боролся я с ними, вызывая в обработчике SIGCHLD функцию wait(). В моей ситуации родителем кто является? Скрипт? Объясните пожалуйста. Если скрипт - то есть ли команда - аналог функции wait()? И подскажите мне вот в чем: мой скрипт срабатывает около 3-х раз (в ситуации, когда программа завершается сама (по exit)), а на 4-й раз появляются зомби. Откуда? И почему не появлялись раньше? А вот когда программа завершается по segmentation fault (то бишь её рубит Линукс, тем же kill наверно), то зомби появляються СРАЗУ.... Я мало что понял из этого объяснения :(... Скрипт не может быть родителем ;) - родителем может быть только породивший процесс, это может быть, например, скриптовый интерпретатор, выполняющий ваш скрипт... P.S. предложение-подсказка - как разобраться в вашей trouble: - сделайте над своим процессом пустую "обёртку", которая будет только exec/spawn ваш процесс... - в ней вы можете перехватывать - наблюдать - обрабатывать все события... - разобравшись что происходит - выбросите обёртку ;). Я б именно так и поступил. Как перехватывать/наблюдать/обрабатывать сигналы неплохо описано тут Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MIkler 0 29 января, 2007 Опубликовано 29 января, 2007 · Жалоба Извините нет времени подробно прочитать тему, я взял из бизибокса реализацию ps дальше брал состояние процесса и всё. В /proc оно вроде отображается. Ну а далее запускаем по крону с нужной частотой. Можно сделать чтобы процесс писал что-то в файлик а другая програмка его анализировала или скрипт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
733259 0 30 января, 2007 Опубликовано 30 января, 2007 (изменено) · Жалоба Может не в тему, но у меня нормально получалось следить, перезапускать процессы из perl, типа foreach $pid(@processes){ if(waitpid($pid,WNOHANG)){ это я к тому, что дспетчер можно и на C написать, но скриптом быстрее, прблем меньше, ИМХО. ЗЫ: пример, буквально за 3 минуты #! /usr/bin/perl -w use strict; use POSIX; my $proc; my @program = ("wget","-c","-t","1","-T","10", "http://download.xilinx.com/direct/webpack/91/WebPACK_SFD_91i.zip"); unless($proc = fork()){ exec(@program); } for(;;){ if(waitpid($proc,WNOHANG)){ if($? != 0){ unless($proc = fork()){ exec(@program); } } } select(undef,undef,undef,0.1); } wget просто так, ничего в голову не пришло Изменено 30 января, 2007 пользователем 733259 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olej 0 2 февраля, 2007 Опубликовано 2 февраля, 2007 · Жалоба to модератор: - эту тему, наверное, нужно перенести в подфорум "Программирование" ? : http://electronix.ru/forum/index.php?showforum=154 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться