返回当前选定的文件句柄。如果提供了 FILEHANDLE,则为输出设置新的当前默认文件句柄。这有两个效果:首先,没有文件句柄的write
、print
或say
默认为此 FILEHANDLE。其次,与输出相关的变量引用将引用此输出通道。
例如,要为多个输出通道设置表单顶部的格式,可以执行以下操作
select(REPORT1);
$^ = 'report1_top';
select(REPORT2);
$^ = 'report2_top';
FILEHANDLE 可以是一个表达式的值,该表达式给出实际文件句柄的名称。因此
my $oldfh = select(STDERR); $| = 1; select($oldfh);
一些程序员可能更愿意将文件句柄视为具有方法的对象,更愿意将最后一个示例写成
STDERR->autoflush(1);
(在 Perl 5.14 之前,必须先明确地use IO::Handle;
。)
虽然你可以使用select
来临时“捕获”print
的输出,如下所示
{
my $old_handle = select $new_handle;
# This goes to $new_handle:
print "ok 1\n";
...
select $old_handle;
}
你可能会发现局部化类型全局变量更容易
{
local *STDOUT = $new_handle;
print "ok 1\n";
...
}
两者并不完全等价,但后者可能更清晰,并且如果包装代码死亡,它将恢复 STDOUT。不同之处在于,在前者中,仍然可以通过在print
语句中明确使用它(如print STDOUT ...
)来访问原始 STDOUT,而在后者中,STDOUT 句柄本身的含义已暂时更改。
可移植性问题:perlport 中的“select”。
这将使用指定的位掩码调用 select(2) 系统调用,可以使用 fileno
和 vec
构建这些位掩码,如下所示
my $rin = my $win = my $ein = '';
vec($rin, fileno(STDIN), 1) = 1;
vec($win, fileno(STDOUT), 1) = 1;
$ein = $rin | $win;
如果您想在许多文件句柄上进行选择,您可能希望编写一个类似这样的子例程
sub fhbits {
my @fhlist = @_;
my $bits = "";
for my $fh (@fhlist) {
vec($bits, fileno($fh), 1) = 1;
}
return $bits;
}
my $rin = fhbits(\*STDIN, $tty, $mysock);
通常的习惯用法是
my ($nfound, $timeleft) =
select(my $rout = $rin, my $wout = $win, my $eout = $ein,
$timeout);
或者,为了在某些内容准备就绪后进行阻塞,只需执行此操作
my $nfound =
select(my $rout = $rin, my $wout = $win, my $eout = $ein, undef);
大多数系统不会费心在 $timeleft
中返回任何有用的内容,因此在标量上下文中调用 select
只会返回 $nfound
。
任何位掩码也可以是 undef
。如果指定了超时,则以秒为单位,可以是分数。注意:并非所有实现都能返回 $timeleft
。如果没有,它们始终返回 $timeleft
等于提供的 $timeout
。
您可以通过这种方式休眠 250 毫秒
select(undef, undef, undef, 0.25);
请注意,select
是否在信号(例如 SIGALRM)后重新启动取决于实现。另请参阅 perlport 以了解有关 select
可移植性的说明。
出错时,select
的行为与 select(2) 完全相同:它返回 -1
并设置 $!
。
在某些 Unix 上,select(2) 可能会将套接字文件描述符报告为“准备好读取”,即使没有可用数据,因此任何后续的 read
都会阻塞。如果您始终在套接字上使用 O_NONBLOCK
,则可以避免这种情况。有关更多详细信息,请参阅 select(2) 和 fcntl(2)。
标准 IO::Select
模块为 select
提供了更友好的用户界面,主要是因为它为您完成了所有位掩码工作。
警告:除了 POSIX 允许的情况外,不应尝试将缓冲 I/O(如 read
或 readline
)与 select
混合,即使在 POSIX 系统上也只允许这样做。您必须改用 sysread
。
可移植性问题:perlport 中的“select”。