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

Multithreading 在线程之间转发/传递文件描述符,multithreading,perl,file-descriptor,shared-objects,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

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

非常简化的代码:

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; }
子线程{
$socket=新IO::socket::INET(…);
# ...
而(我的$client=$socket->accept()){
#如果我打印STDOUT,(fileno$client)#在那里我会得到4个
推送(@shared,fileno$client);
}
}
副主线程{
if(标量@共享){
$fd=共享时的移位;
#如果我打印(fileno$fd);#在那里我会得到4个

打开my$f,“
my$client
创建一个作用域为循环体的变量。在过程结束时,放弃对包含句柄的最后一次引用,释放文件句柄,从而关闭关联的文件描述符。[1]


这在另一个线程到达
打开之前发生注意:始终
使用严格;使用警告“全部”;
!您有许多范围不正确的变量,这将帮助您发现这些问题。注意:
正如您所说的更改“还在线程中添加了粘贴的codeChanging
,我只需要接受连接,然后线程继续执行其工作,等待新的连接。它从不关闭文件描述符。所有文件读取/写入和关闭都在另一个工作线程中执行。因此我确切地知道它不会关闭FD。我确切地知道连接不会通过客户端,因为它使用其他软件进行了测试。Re“它从不关闭文件描述符”,您显示的代码确实如此。下次分配给
$a
时,您将删除以前包含的对
$a
句柄的最后一个引用,导致基础fd关闭。请解释如果它隐式关闭文件描述符,我在代码中有一个错误:$a=$socket->accept()应该是我的$a=$socket->accept()由于您像我一样使用词法(
my
)变量,因此隐式关闭变量的位置与我在演示中的位置完全相同,在作用域的末尾,它显示“File handle closed here”。///更新了我的答案以反映更新后的问题。非常感谢。我理解了。 perl -w ./testcode.pl --port=10102 & wget -O - http://127.0.0.1:10102/
#!/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
}