我有一个任务,我在一个线程中等待连接并将它们转发到另一个线程。 也许我有些误解,但为什么我不能在主线程中重新打开文件描述符?
非常简化的代码:
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/
答案 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键入的数组或散列中,而另一个线程可以让父线程知道通过另一个共享结构处理它不再需要的那个。
close $client;
时,文件描述符会被关闭。