Вопрос № 89484: Здравствуйте доргие эксперты!
Я не так давно изучаю Perl, доконца еще не разобрался в его возможностях. Помогите пожалуйста решить такуж задачу:
Требуется запустить параллельный процесс, подождав несколько секунд убить его (в принципе `killal...
Вопрос № 89.484
Здравствуйте доргие эксперты!
Я не так давно изучаю Perl, доконца еще не разобрался в его возможностях. Помогите пожалуйста решить такуж задачу:
Требуется запустить параллельный процесс, подождав несколько секунд убить его (в принципе `killall` подойдет, хотя может и кроссплатформенная реализация тоже будет интересна), получить от него вывод, желательно напрямую в переменную.
Заранее благодарю всех ответивших!!!!
Отвечает: dianacode
Доброе время суток, Казаков М.А. / gnom
предлагаю вариант для никсов - fork:
1) родитель создаёт потомка
2) пока потомок выполняется, родитель слушает сигналы от потомка
3) когда потомок завершит выполнение кода он посылает родителю сигнал CHLD
4) родитель, зная, что потомков запущено $countch, и, подсчитав все сигналы от них (в данном случае один) говорит, что все процессы являются defunct, т.е. зомбаками и завершает цикл ожидания while
5) запускается функция на уничтожение зомби
немного теории :: зомби будет висеть до тех пор, пока к нему не обратятся с waitpid или не завершится срипт
со всеми вопросами на форум ^_^
пример кода с комментариями ниже
our $zCounter = 0;
$SIG{CHLD} = sub{ $zCounter++ }; # приём родителя сигналов от потомков и увеличение счётчика принятых сигналов
my $countch = 1;
unless(my $ch = fork){ # старт потомка
print "[c] child is started...
";
my $i = 0;
for(1..5){
print '[c] child ', ++$i, "
";
sleep 1;
}
print "[c] zomb...
";
exit;
}
while(1){
select(undef, undef, undef, 0.5); # пауза в 500 миллисекунд
if($zCounter >= $countch){ # выходим если все потомки отправили предку сигналы CHLD
print "all child is zomb...
";
}
}
&killer; # обязательный вызов киллера для ждущих мёртвых процессов
print "all finished...
";
sub killer{
print "garbage collector is active with $zCounter zomb...
";
$zCounter = 0;
while((my $zomb = waitpid(-1, &WNOHANG)) != -1){
print "zomb $zomb killed with status '$?'...
";
}
}
с уважением, удачи
Приложение:
--------- there is more than one way to do it
Ответ отправила: dianacode (статус: Студент)
Ответ отправлен: 31.05.2007, 21:50
Отвечает: lupus campestris
Здравствуйте, Казаков М.А. / gnom!
Я использую такой вариант (под Windows): дочерний скрипт при запуске записывает свой pid в файл, и при необходимости родительский скрипт считывает его pid и убивает его, после чего удаляет файл с pid'ом дочернего процесса, уже убитого. Если нет необходимости убивать дочерний процесс, то нужно удалять файл с pid'ом после выполнения дочернего процесса.
Используется утилита kill из Support Tools, которые есть на диске с дистрибутивом Windows, но можно и на сайте microsoft.com их скачать.
Для работы в никсовых системах можно использовать стандартную утилиту kill с параметром -9.
Что касается вывода, то я в дочернем процессе делаю просто print, а в родительском при запуске направляю вывод дочернего скрипта в файл.
См. приложение.
Удачи!
Приложение:
--------- «С кем тяжело молчать, с тем не о чем говорить» (Метерлинк)
Ответ отправила: lupus campestris (статус: Профессор) Россия, Москва Тел.: +79060429689 Организация: http://www.orange-business.ru WWW:http://lupus-campestris.blogspot.com/ ICQ: 193918889 ---- Ответ отправлен: 05.06.2007, 14:01