Re: как насильно прибить запущенные процессы?

From
Andrey Sapozhnikov (2:5020/400)
To
Dmitry Sukhodoev (2:5054/37.63)
Date
2005-05-12T19:20:40Z
Area
RU.PERL
From: Andrey Sapozhnikov <sapa@icb.chel.su>

Dmitry Sukhodoev wrote:
> запускаю некую связку:
> open(HANDLE, 'program1 | program2 |');
> 
> program1 выдаёт на stdout очень большой объём данных, а program2 эти 
> данные очень долго жуёт и периодически что-то валит на stdout.
> 
> мне нужно дождаться чего-то своего от program2 и сделать exit, чтобы и 
> program1 и program2 завершились. если просто сделать exit, то мой скрипт 
> ждёт, пока они завершаться сам, а мне их надо бы насильно грохнуть, 
> можно через kill -9.
> 
> но проблема в том, что kill -9 я использовать не могу, т.к. не знаю pid 
> этих двух процессов, а open возвращает pid шела, через который эти два 
> процесса запущены. подскажите что-нить разумное, плз, чтобы pipe через 
> себя не гонять и чтобы рыбку съесть :)
> 

1. Можно зашибить всю группу. См. perldoc -f kill про отрицательные
значения сигналов.
2. Ежели нужен индивидуальный подход (ну скажем одного зашибить
так, другого эдак или в нужном порядке) или какая-то собака отрывает
себя от группы (man setpgrp, man setsid) или группы не поддерживаются
в данной ОС, то придется организовавать пайпы и вызывать процессы самому.
Через себя ничего гонять не придется. Схематически:

pipe (RP1, WP1) or die "pipe: $!";

my $pid1 = fork();
die "fork: $!" unless defined $pid1;

unless ($pid1) { # Child1
     close (RP1);
     open(STDOUT, ">&WP1") or die "dup: $!";
     close (WP1);
     exec("program1") or die "exec: $!";
}

close (WP1);

pipe (RP2, WP2) or die "pipe: $!";

my $pid2 = fork();
die "fork: $!" unless defined $pid2;

unless ($pid2) { # Child2
     open(STDIN, "<&RP1") or die "dup: $!";
     close (RP1);

     close (RP2);
     open(STDOUT, ">&WP2") or die "dup: $!";
     close (WP2);
     exec("program1") or die "exec: $!";
}

close (RP1)
close (WP2);

$SIG{ALRM} = sub {
     kill 15, $pid1;
     kill 15, $pid2;
};
alarm(60);
...
while(read(RP2, ...)) {
...
}
...
waitpid($pid1, 0);
waitpid($pid2, 0);

-- 
Андрей
--- ifmail v.2.15dev5.3
 * Origin: Demos online service (2:5020/400)
SEEN-BY: 50/203 520 400/462 450/159 186 208 451/30 452/25 100 454/9 455/15
SEEN-BY: 461/33 43 74 106 132 640 464/34 465/204 467/24 469/125 200 999 478/44
SEEN-BY: 478/65 550/150 5068 4600/126 4614/9 4616/3 4623/56 4625/8 9 4626/100
SEEN-BY: 4627/10 4632/10 4635/4 99 1024 4641/444 4642/27 48 4657/50 5000/76
SEEN-BY: 5001/50 5001 5002/76 5002 5003/34 5006/1 5007/1 5010/53 70 146
SEEN-BY: 5011/13 5012/8 5015/4 28 214 5019/5 5020/52 115 118 128 133 150 154
SEEN-BY: 5020/175 194 400 486 545 549 600 642 715 744 758 794 830 921 958 968
SEEN-BY: 5020/982 1057 1100 1169 1212 1234 1523 1604 1626 1642 1653 1665 1826
SEEN-BY: 5020/1829 1922 1930 2013 2020 2044 2142 2200 2238 2345 2590 2908 4400
SEEN-BY: 5020/4441 5021/2 3 5022/128 5023/11 5024/1 73 5025/19 750 5026/14 49
SEEN-BY: 5030/49 69 195 382 436 556 611 920 966 1016 1039 1063 1339 1520 1688
SEEN-BY: 5030/1900 5031/7 47 63 70 5032/11 20 5033/21 35 5034/8 5035/3 38 63
SEEN-BY: 5036/1 13 5037/21 36 5038/4 5040/33 47 5041/4 5042/13 5045/7 42
SEEN-BY: 5047/47 5049/1 6 157 5050/9 41 5051/15 35 5053/16 38 5054/1 8 9 35 36
SEEN-BY: 5054/37 45 50 66 67 81 85 5055/177 5056/16 5057/1 5058/77 5059/2 9 20
SEEN-BY: 5060/88 90 5061/15 5062/1 4 7 5063/51 5064/7 35 39 5066/18 5070/26 66
SEEN-BY: 5070/948 1222 5071/22 5075/5 37 5077/70 80 5079/49 5080/80 1003
SEEN-BY: 5081/2 5082/6 5083/13 21 5090/23 105 108 113 5093/4 27 33 5096/18
SEEN-BY: 5100/113 6001/3 6023/1 6033/2727 6035/9 6070/5 6083/11 6096/10
PATH: 5020/400 4441 52 5054/1 37