Forward/pass 线程间的文件描述符

Forward/pass file descriptors between threads

我有一个任务,我正在等待一个线程中的连接并将它们转发到另一个线程。 也许我误解了什么,但为什么我不能在主线程中重新打开文件描述符?

非常简化的代码:

sub inthread {
    $socket = new IO::Socket::INET ( ... );
    # ...
    while ( my $client = $socket->accept() ) {
       #if i print STDOUT, (fileno $client); # there i'll get 4
       push ( @shared, fileno $client);
    }
}


sub mainthread {
   if ( scalar @shared ) {
      $fd = shift @shared;
      # if i print (fileno $fd); # there i'll get 4
      open my $f, "<&=$fd" or die " error $!"; ### error here: Can't open 4: Bad file descriptor
      while ( <$f> ) { ... }
   }
}

threads->create(\&inthread);
while(1) { mainthread; }

完整代码在那里http://dpaste.com/3381RKV

测试:

perl -w ./testcode.pl --port=10102 &
wget -O - http://127.0.0.1:10102/

my $client 创建一个作用域为循环体的变量。在传递结束时,放弃对所包含句柄的最后引用,释放文件句柄,关闭关联的文件描述符。[1]

这发生在另一个线程到达 open <&= 之前,因此当您尝试为其创建新文件句柄时文件描述符不再有效。

独立演示:

#!/usr/bin/perl

use strict;
use warnings;

my $fd;

{
   open(my $fh, '<', [=10=])
      or die($!);

   $fd = fileno($fh);
}                               # File handle closed here.

{
   open(my $fh, '<&=', $fd)
      or die($!);               # Bad file descriptor
}

您必须确保文件句柄不会过早关闭。您可以将它们存储在由 fd 键入的数组或散列中,另一个线程可以让父线程知道哪个处理它不再需要通过另一个共享结构。


  1. 在您在评论中链接的代码中(与您发布的代码相反),文件描述符在您调用 close $client;.
  2. 时关闭