Sorry for later. http://perlchina.org/advent/2009/ParallelSig.html
=for advent_year 2009 =for advent_day 18 =for advent_title Parallel::Prefork 和 SIG =for advent_author Fayland Lam 如果一个 daemon 处理队列太慢(或其他情况),M<Parallel::ForkManager> 和 M<Parallel::Prefork> 都是很不错的选择。 下面的代码来自我们实际运行中的一个 M<TheSchwartz> worker 的 daemon, 实际上很大一部分都是拷贝自 A<http://d.hatena.ne.jp/tokuhirom/20081110/1226291955> =begin codeNNN use strict; use warnings; my $has_proc_pid_file = eval 'use Proc::PID::File; 1;'; ## no critic (ProhibitStringyEval) my $has_home_dir = eval 'use File::HomeDir; 1;'; ## no critic (ProhibitStringyEval) if ( $has_proc_pid_file and $has_home_dir ) { # If already running, then exit if ( Proc::PID::File->running( { dir => File::HomeDir->my_home } ) ) { exit(0); } } use UNIVERSAL::require; use Parallel::Prefork; my @workers = qw/ TheSchwartz::JobA TheSchwartz::JobB TheSchwartz::JobC /; foreach my $worker (@workers) { print "setup $worker\n"; $worker->use or die $@; } sub MaxRequestsPerChild () { 2 } print "start prefork\n"; my $pm = Parallel::Prefork->new({ max_workers => 3, fork_delay => 1, trap_signals => { TERM => 'TERM', HUP => 'TERM', }, }); while ($pm->signal_received ne 'TERM') { $pm->start and next; print "spawn $$\n"; my $client = TheSchwartz::Moosified->new( databases => [$dbh] ); $client->can_do($_) foreach @wokers; my $reqs_before_exit = MaxRequestsPerChild; $SIG{TERM} = sub { $reqs_before_exit = 0 }; while ($reqs_before_exit > 0) { if ($client->work_once) { print "work $$\n"; --$reqs_before_exit; } else { sleep 10; } } print "FINISHED $$\n"; $pm->finish; } $pm->wait_all_children; die "HMM????"; =end codeNNN 代码是自解释的。:) 但是有时候我们需要停止它的时候(它由 crontab 启动),根据代码我们需要发送 TERM 给脚本,然后脚本才会优雅地退出。这时候 M<Proc::ProcessTable> 就派上大用场了。 =begin codeNNN use Proc::ProcessTable; my $p = new Proc::ProcessTable( 'cache_ttys' => 1 ); my $all = $p->table; foreach my $one (@$all) { if ($one->cmndline =~ /TheSchwartz/) { next if ( $one->cmndline =~ /TheSchwartz_restart/ ); # itself my $pid = $one->pid; print "kill -15 $pid\n"; `kill -15 $pid`; # send TERM } } =end codeNNN Proc::ProcessTable 类似于 ps, 我们找到 pid 后,发送 TERM 过去就大功告成了。 谢谢。 -- Fayland Lam // http://www.fayland.org/ -- 您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。 要向此网上论坛发帖,请发送电子邮件至 [email protected]。 要取消订阅此网上论坛,请发送电子邮件至 [email protected]。 若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。
