在线程之间转发/传递文件描述符

时间:2016-07-29 15:49:15

标签: multithreading perl file-descriptor shared-objects

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

非常简化的代码:

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/

1 个答案:

答案 0 :(得分:6)

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

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

自足示范:

#!/usr/bin/perl

use strict;
use warnings;

my $fd;

{
   open(my $fh, '<', $0)
      or die($!);

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

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

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

  1. 在您在评论中链接的代码中(而不是您发布的代码),当您致电close $client;时,文件描述符会被关闭。