现在的位置: 主页 > 新闻中心 > 文章列表

perl实现超时机制综述

作者:北京财贸天阶投资顾问有限公司 来源:www.usasheng.com 发布时间:2017-09-03 12:45:12
 

perl实现超时机制综述 一、ALARM方式

示例程序:

#!/usr/bin/perl

$timeout = 2 ;

while(1)

{

eval {

local $SIG{ALRM} = sub{print "sorry,time out.please try again\n"} ;

alarm $timeout ; #启动定时器

# 实际操作

print "hello world!\n" ;

sleep 3 ;

alarm 0 ; #取消定时器

} ;

die $@ if $@ ;

}

说明:

将实际操作放在eval块中。

首先,初始化一个本地化的ALRM信号处理器,它位于特殊的%SIG哈希里。

假如触发了该处理器,它会调用die()并且中断eval块。然后可以根据$SIG{ALRM}信号处理程序来做相应的处理。

大多数情况下,你可能需要向用户报告,站群系统,操作已超时。

实际的操作放在2个alarm()调用之间。

第一个alarm开始计时器,第二个取消它。这里计时器运行10秒。

假如在指定的时间里,采集软件,第二个alarm没有发生,则产生SIGALRM信号,存储在$SIG{ALRM}里的处理器被调用。

假如在第二个alarm在设定的秒内完成,alarm时钟会终止,eval块成功返回,不会触发ALRM处理器。

注意:

在给定时间内,仅仅一个计时器可用。alarm()的返回值是剩余时间的数量。

所以实际上可利用这点来粗略的估计执行时间。

二、父子进程方式

通过fork(), 产生子进程,让子进程执行实际操作;

父进程中设置时间门限sleep();

若子进程成功执行则会自动激发$SIG{CHLD}消息,在消息处理里收集状态;

若不成功,则在父进程中使用kill杀死子进程,

此时也会激发$SIG{CHLD}消息,调用waitpid收集僵尸。并处理状态。

示例:

用Perl 给命令加上超时退出的功能

#! /usr/bin/env perl

use POSIX qw(strftime WNOHANG);

#check input

my $timeout = shift @ARGV;

my ($secs) = $timeout =~ /--timeout=(\d+)$/;

unless($secs)

{

print "Usage: ./timeout --timeout=[SECONDS] [COMMAND] \n";

exit -1;

}

#fork and exec

my $status = 0;

$SIG{CHLD} = sub

{

while(waitpid(-1,WNOHANG)>0)

{

$status = -1 unless $? == 0;

exit $status;

}

};

$0 = 'timeout hacked ' . $ARGV[0];

defined (my $child = fork);

if($child == 0)

{

my $cmd = join ' ', @ARGV;

exec($cmd);

}

$SIG{TERM} = sub { kill TERM => $child };

$SIG{INT} = sub { kill INT => $child };

#kill when timeout

sleep $secs;

$status = -1;

kill TERM => $child;

sleep 1 and kill INT => $child if kill 0 => $child;

sleep 1 and kill KILL => $child if kill 0 => $child;

exit $status;

如下调用, 就可以让任意的命令超时退出了(这里执行的命令是“sleep 500”)

./timeout.pl --timeout=3 sleep 500

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:天门网站制作 http://tianmen.666rj.com

  • 上一篇:jQuery参考实例 1.11 移除DOM元素
  • 下一篇:最后一页
  •