the best way to replace regular alarm

I need to implement less-than-a-second timeouts in the DBIx::HA package. Having the following code from that module:

my $timeout = 0;
eval {
    no strict;
    my $h = set_sig_handler(
        'ALRM', 
        sub { $timeout = 1; die 'TIMEOUT'; },
        { mask=>['ALRM'], safe=>1 }
    );
    alarm($DATABASE::conf{_getdbname($dsn)}->{'connecttimeout'});
    $dbh = DBI->connect($dsn, $username, $auth, $attrs);
    alarm(0);
};

I know that there is a core Perl module Time::HiRes, but I never used it before. It also has an alarm() sub - may I just insert use Time::HiRes qw (alarm); before the lines above? Or maybe I should somehow adapt the lines above? I haven't found any obvious example.


You can do exactly as you said. All you need to do is load Time::HiRes and import alarm before you call the code. But please don't put it directly above the code, it's not good practice to have use statements all over the place. It belongs to the top.

The Time::HiRes doc says ( emphazis mine ):

alarm ( $floating_seconds [, $interval_floating_seconds ] )

The SIGALRM signal is sent after the specified number of seconds. Implemented using setitimer() if available, ualarm() if not. The $interval_floating_seconds argument is optional and will be zero if unspecified, resulting in alarm()-like behaviour. This function can be imported, resulting in a nice drop-in replacement for the alarm provided with perl , see the "EXAMPLES" below.

Then later on there is this example (quoted verbatim) that nicely shows that you can use floating-point values with alarm now.

use Time::HiRes qw ( time alarm sleep );
$now_fractions = time;
sleep (2.5);
alarm (10.6666666);

OK, I'm still having some minor issues, but I doubt they are connected to Time::HiRes, and in general the following solution actually works:

use Time::HiRes qw (alarm); # Just adding this line.... ;)
my $timeout = 0;
eval {
    no strict;
    my $h = set_sig_handler(
        'ALRM', 
        sub { $timeout = 1; die 'TIMEOUT'; },
        { mask=>['ALRM'], safe=>1 }
    );
    alarm($DATABASE::conf{_getdbname($dsn)}->{'connecttimeout'});
    $dbh = DBI->connect($dsn, $username, $auth, $attrs);
    alarm(0);
};

Good to know! :D

链接地址: http://www.djcxy.com/p/59224.html

上一篇: 为什么我不能将此perl子分配给一个变量?

下一篇: 取代常规警报的最佳方法