Наясно съм с многото въпроси относно waitpid и timeouts, но всички те покриват това, като убиват детето от манипулатора на аларми.
Това не е това, което искам, искам да продължа процеса да работи, но да го изпратя от waitpid.
Основният проблем, който се опитвам да разреша, е процес на демон с основен цикъл, който обработва опашка. Задачите се обработват една по една.
Ако дадена задача увисне, целият основен цикъл увисва. Заобикалянето на тези fork()
и waitpid
изглеждаше очевиден избор. И все пак, ако задачата виси, цикълът виси.
Мога да се сетя за заобиколни решения, при които изобщо не използвам waitpid, но ще трябва да проследявам изпълняваните процеси по друг начин, тъй като все още искам да обработвам една задача наведнъж успоредно с евентуално висящи задачи.
Бих могъл дори да убия задачата, но бих искал да я пусна, за да проверя какво точно се обърка. Възможен е също манипулатор за унищожаване, който изхвърля информация за отстраняване на грешки.
Както и да е, най-удобният начин за решаване на този проблем е изчакване за чакане, ако е възможно.
Редактиране:
Ето как използвах fork() и waitpid и може да е по-ясно какво се има предвид под дете.
my $pid = fork();
if ($pid == 0){
# i am the child and i dont want to die
}
elsif ($pid > 0) {
waitpid $pid, 0;
# i am the parent and i dont want to wait longer than $timeout
# for the child to exit
}
else {
die "Could not fork()";
}
Редактиране:
Използването на waitpid WNOHANG прави това, което искам. Това използване добра практика ли е или бихте го направили по различен начин?
use strict;
use warnings;
use 5.012;
use POSIX ':sys_wait_h';
my $pid = fork();
if ($pid == 0){
say "child will sleep";
sleep 20;
say "child slept";
}
else {
my $time = 10;
my $status;
do {
sleep 1;
$status = waitpid -1, WNOHANG;
$time--;
} while ($time && not $status );
say "bye";
}