我有多个阻止TCP客户端尝试连接并向服务器发送数据。但是,每个操作的时间不应超过500毫秒,因为数据与时间有关。超时时,应该再试一次。我见过alarm()
方法,但只接受秒。这样做有好办法吗?
答案 0 :(得分:2)
Time::HiRes模块为您提供了具有微秒粒度的函数ualarm
。
答案 1 :(得分:2)
如果您有每个连接的子进程,则可以使用Time::HiRes的ualarm
。否则,我不明白为什么你甚至想要使用alarm
。它甚至不会帮助线程(因为信号被发送到进程)。
更好的方法是记下建立连接的时间,如果从接下来的0.5秒后接收到来自客户端的数据,则删除连接。 Time :: HiRes提供了一个返回小数秒的time
版本。
无论您如何提供并行性(线程,子进程,select
,非阻塞操作),此方法都有效。它适用于TCP和UDP。它甚至可以携带。
如果所有内容都在同一个线程和进程中,那么每当从任何连接获取数据时,都可以通过扫描所有连接超时来尽快删除死连接。
alarm
不会帮助您使用线程。
如果在启动线程之前设置处理程序,则线程中的调用不会中断。
use strict;
use warnings;
use threads;
use Time::HiRes qw( time ualarm );
local $SIG{ALRM} = sub { };
{
ualarm(2 * 1_000_000);
my $s = time;
sleep(5);
my $e = time;
print "Slept for ".($e-$s)." seconds\n";
}
for my $thread_idx (0..1) {
async {
ualarm(2 * 1_000_000) if $thread_idx == 0;
my $s = time;
sleep(5);
my $e = time;
print "Thread $thread_idx slept for ".($e-$s)." seconds\n";
};
}
$_->join for threads->list;
输出
Slept for 2.00284504890442 seconds
Thread 0 slept for 5.00048089027405 seconds
Thread 1 slept for 5.00327205657959 seconds
在线程中设置处理程序根本没有任何影响。
use strict;
use warnings;
use threads;
use Time::HiRes qw( time ualarm );
for my $thread_idx (0..1) {
async {
local $SIG{ALRM} = sub { };
ualarm(2 * 1_000_000) if $thread_idx == 0;
my $s = time;
sleep(5);
my $e = time;
print "Thread $thread_idx slept for ".($e-$s)." seconds\n";
};
}
$_->join for threads->list;
输出
Alarm clock