我有多个阻塞TCP客户端试图连接并发送数据到服务器。但是,每个操作不应超过500ms,因为数据是时间相关的。在超时时,它应该再试一次。我见过alarm()
方法,但它只接受秒。有什么好办法吗?
Time::HiRes模块为您提供了一个微秒粒度的函数ualarm
。
如果每个连接都有一个子进程,则可以使用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)." secondsn"; } 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)." secondsn"; }; } $_->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)." secondsn"; }; } $_->join for threads->list;
Alarm clock