use IO::Select; my $s = new IO::Select; $s->add($h1); $s->add($h2); my (%handler, %buf); $handler{$h1} = sub { ...handle a line from $h1... }; $handler{$h2} = sub { ...handle a line from $h2... }; while ($s->count) { my @ready = $s->can_read(); for my $h (@ready) { my $nr = sysread($h, $buf{$h}, 1024, length($buf{$h})); if ($nr == 0) { # eof detected $s->remove($h); } else { if ($buf{$h} =~ s/\A(.*?)\n//) { $handler{$h}->($1); } } } }