如何消除计时过程或卡住过程(通过
system
命令)使用Perl。
如何杀死使用system
命令启动的进程,花费太多时间或卡在某处。
答案 0 :(得分:2)
如果您希望在同一个脚本中杀死system()调用的进程,则无法获取其PID或将其终止,因为system()调用在进程完成之前不会返回。相反,您可以使用fork()创建一个新进程,并执行最初由exec()在新创建的进程中由system()调用的进程。 fork()将返回子进程的PID,然后您可以随时使用kill()将其终止。
http://perldoc.perl.org/functions/fork.html
答案 1 :(得分:2)
Perl FAQ的第8部分包含
How do I timeout a slow event?
使用
alarm
函数,可能与信号处理程序一起使用,如Signals in perlipc和Camel中“信号”部分所述。您可以使用CPAN提供的更灵活的Sys::AlarmCall模块。在所有版本的Windows上未实现
alarm
功能。查看特定版本Perl的文档。
“Signals” section of the perlipc documentation包含
信号处理也用于Unix中的超时。虽然在
eval{}
块内安全地受到保护,但您可以设置一个信号处理程序来捕获警报信号,然后安排在一定时间内将一个警报信号传送给您。然后尝试阻止操作,在完成后清除闹钟,但在退出eval{}
块之前不要。如果它熄灭,您将使用die
跳出块。以下是一个例子:
my $ALARM_EXCEPTION = "alarm clock restart"; eval { local $SIG{ALRM} = sub { die $ALARM_EXCEPTION }; alarm 10; flock(FH, 2) # blocking write lock || die "cannot flock: $!"; alarm 0; }; if ($@ && $@ !~ quotemeta($ALARM_EXCEPTION)) { die }
如果超时的操作是
system
或qx
,则此技术可能会生成僵尸。如果这对您很重要,您需要自己执行fork
和exec
,并杀死错误的子进程。对于更复杂的信号处理,您可能会看到标准的POSIX模块。可悲的是,这几乎完全没有记录,但Perl源代码分发中的
t/lib/posix.t
文件中有一些例子。
答案 2 :(得分:0)
建议使用fork和exec,主要是作为安全预防措施(用户输入)。
但是如果你不关心用户输入并且知道你已经开始使用系统的过程,那么你可以打开一个管道到任务列表或ls调用,用grep处理它们以找到你烦恼的过程然后向这些进程发送kill信号。