To use this solution it should be able to pass a socket from main program listener to a worker thread. Is there any way to accomplish this?
| [reply] |
A simple but reasonably complete, pooled, threaded echo server:
Update: Added sig handler to close it down cleanly.
#! perl -slw
use strict;
use threads;
use threads::shared;
use Thread::Queue;
use IO::Socket;
my $semSTDOUT :shared;
sub tprint{ lock $semSTDOUT; print @_; }
$|++;
my %cache;
my $Qwork = new Thread::Queue;
my $Qdone = new Thread::Queue;
my $done :shared = 0;
sub worker {
my $tid = threads->tid;
while( my $fno = $Qwork->dequeue ) {
open my $client, "+<&", $fno or die $!;
tprint "$tid: Duped $fno to $client";
while( <$client> ) {
printf $client "%s", $_;
chomp;
tprint "$tid: got and echoed $_";
last if $done;
}
close $client;
$Qdone->enqueue( $fno );
tprint "$tid: $client closed";
}
}
our $W //= 4;
my $lsn = new IO::Socket::INET(
Listen => 5, LocalPort => '12345'
) or die "Failed to open listening port: $!\n";
my @workers = map threads->create( \&worker, \%cache ), 1 .. $W;
$SIG{ INT } = sub {
close $lsn;
$done = 1;
$Qwork->enqueue( (undef) x $W );
};
while( my $client = $lsn->accept ) {
my $fno = fileno $client;
$cache{ $fno } = $client;
$Qwork->enqueue( $fno );
delete $cache{ $Qdone->dequeue } while $Qdone->pending;
}
tprint "Listener closed";
$_->join for @workers;
tprint "Workers done";
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |