如何为多个TCP连接指定以毫秒为单位的连接和发送超时?



我有多个阻塞TCP客户端试图连接并发送数据到服务器。但是,每个操作不应超过500ms,因为数据是时间相关的。在超时时,它应该再试一次。我见过alarm()方法,但它只接受秒。有什么好办法吗?

Time::HiRes模块为您提供了一个微秒粒度的函数ualarm

如果每个连接都有一个子进程,则可以使用Time::HiRes的ualarm。否则,我不明白为什么你甚至想使用alarm。它甚至不能帮助线程(因为信号被发送给进程)。

更好的方法是记录连接建立的时间,如果从客户端接收数据超过0.5秒,则放弃连接。Time::HiRes提供了一个版本的time,它返回小数秒。

无论你如何提供并行性(线程、子进程、select、非阻塞操作),这种方法都有效。它适用于TCP和UDP。而且它还很便携。

如果所有东西都在同一个线程和进程中,那么无论何时从任何连接获得数据,都可以通过扫描所有连接的超时时间来更快地删除死连接。


alarm不能帮助你处理线程。

  1. 如果在启动线程之前设置处理程序,则线程中的调用不会中断。

    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
    
  2. 在线程中设置处理程序没有任何影响。

    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
    

相关内容

  • 没有找到相关文章

最新更新