perl实现超时机制综述
来源:互联网 发布:房屋装修设计图软件 编辑:程序博客网 时间:2024/05/17 03:19
一、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
参考文章:
1. http://blog.yikuyiku.com/?tag=perl
2. http://fuzhong1983.blog.163.com/blog/static/16847052010101624315872/
示例程序:
#!/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
参考文章:
1. http://blog.yikuyiku.com/?tag=perl
2. http://fuzhong1983.blog.163.com/blog/static/16847052010101624315872/
- perl实现超时机制综述
- perl&LWP 综述
- Perl线程综述
- Java任务超时处理机制实现
- [转] 网卡超时实现机制 watchdog_timeo/ndo_tx_timeout
- Netty 超时机制及心跳程序实现
- 网卡超时实现机制 watchdog_timeo/ndo_tx_timeout
- Netty 超时机制及心跳程序实现
- perl lwp 超时问题
- perl 异步超时 打印错误
- 如何用信号来实现超时的读写机制
- 用CancellableTask实现TCP连接请求超时机制
- Linux 多线程等待超时机制的实现:pthread_mutex_lock/pthread_cond_signal/pthread_mutex_unlock
- Linux C++ 实现时间轮 优化超时检测机制
- 基于select模型的udp客户端实现超时机制
- Golang RPC调用例子程序(实现超时机制)
- 异常机制综述
- javascript继承机制综述
- SH Application Binary Interface for GCC
- SYS_CONNECT_BY_PATH 学习
- Hyper-v相关补丁(错误号87 Virtual Machine Management服务无法启动)
- android bundler机制
- [转载]深度学习(Deep Learning)综述及算法简介[转]
- perl实现超时机制综述
- ajax的xmlHttpRequest对象
- 浅谈无缓存I/O操作和标准I/O文件操作区别
- 在T-SQL语句中访问远程数据库(openrowset/opendatasource/openquery)
- Android应用性能优化之使用SparseArray替代HashMap
- MATLAB矩阵行列式
- 山东轻工业学院CSDN高校俱乐部“到底谁动了谁的iPad”辩论赛成功举办
- uva 1388 - Graveyard
- frameset框架设置指定的宽度是1400并且居中显示