IO::Select 并为句柄添加标签
IO::Select and adding a tag to the handle
我想知道在使用 IO::Select
时向句柄添加额外数据的最佳方式是什么?
基本上我想为 IO::Select
添加句柄,但也有附加信息附加到该句柄,我可以稍后检索。
注意:我知道我可以保留一个单独的数据结构来保存句柄和附加数据,但这需要协调两个数据结构,这可能会导致比其价值更多的问题。
add
方法
的 IO::Select 文档提供了一种直接方法
Each handle can be an IO::Handle object, an integer or an array reference where the first element is an IO::Handle or an integer.
所以,有 "an array reference" 可以使用。
一个例子:
use warnings;
use strict;
use feature 'say';
use Time::HiRes qw(sleep);
use POSIX qw(:sys_wait);
use IO::Select;
my $sel = IO::Select->new;
my @procs;
for my $job (1..3) {
pipe my ($reader, $writer);
$sel->add( [$reader, "job-$job"] ); # add a tag to the handle
my $pid = fork // die "Can't fork: $!";
if ($pid == 0) {
close $reader;
sleep rand 4;
say $writer "\tkid $$ (job $job)";
close $writer;
exit;
}
close $writer;
push @procs, $pid;
}
say "Started processes @procs\n";
# Read from pipes when ready, print piped messages
while ( my @ready = $sel->can_read ) {
foreach my $p (@ready) {
my ($handle, $tag) = @$p;
say "Reading from fileno ", $handle->fileno, ", tag: ", $tag;
print while <$handle>;
$sel->remove($p); # *this* order: remove then close
close $handle;
}
}
# Reap
my $msg = "\nExited (with status): ";
my $kid = 0; # poll to reap
while (($kid = waitpid -1, WNOHANG) > -1) {
$msg .= "$kid ($?) " if $kid > 0;
sleep 0.1;
}
say $msg;
版画
Started processes 15679 15680 15681
Reading from fileno 5, tag: job-2
kid 15680 (job 2)
Reading from fileno 4, tag: job-1
kid 15679 (job 1)
Reading from fileno 6, tag: job-3
kid 15681 (job 3)
Exited (with status): 15680 (0) 15679 (0) 15681 (0)
我想知道在使用 IO::Select
时向句柄添加额外数据的最佳方式是什么?
基本上我想为 IO::Select
添加句柄,但也有附加信息附加到该句柄,我可以稍后检索。
注意:我知道我可以保留一个单独的数据结构来保存句柄和附加数据,但这需要协调两个数据结构,这可能会导致比其价值更多的问题。
add
方法
Each handle can be an IO::Handle object, an integer or an array reference where the first element is an IO::Handle or an integer.
所以,有 "an array reference" 可以使用。
一个例子:
use warnings;
use strict;
use feature 'say';
use Time::HiRes qw(sleep);
use POSIX qw(:sys_wait);
use IO::Select;
my $sel = IO::Select->new;
my @procs;
for my $job (1..3) {
pipe my ($reader, $writer);
$sel->add( [$reader, "job-$job"] ); # add a tag to the handle
my $pid = fork // die "Can't fork: $!";
if ($pid == 0) {
close $reader;
sleep rand 4;
say $writer "\tkid $$ (job $job)";
close $writer;
exit;
}
close $writer;
push @procs, $pid;
}
say "Started processes @procs\n";
# Read from pipes when ready, print piped messages
while ( my @ready = $sel->can_read ) {
foreach my $p (@ready) {
my ($handle, $tag) = @$p;
say "Reading from fileno ", $handle->fileno, ", tag: ", $tag;
print while <$handle>;
$sel->remove($p); # *this* order: remove then close
close $handle;
}
}
# Reap
my $msg = "\nExited (with status): ";
my $kid = 0; # poll to reap
while (($kid = waitpid -1, WNOHANG) > -1) {
$msg .= "$kid ($?) " if $kid > 0;
sleep 0.1;
}
say $msg;
版画
Started processes 15679 15680 15681 Reading from fileno 5, tag: job-2 kid 15680 (job 2) Reading from fileno 4, tag: job-1 kid 15679 (job 1) Reading from fileno 6, tag: job-3 kid 15681 (job 3) Exited (with status): 15680 (0) 15679 (0) 15681 (0)