Provided that you create the threads before loading your data, a threaded server works fine. Only the main thread has a copy of the large volume of data, whilst sharing the requests and replies with the server threads through shared memory (Thread::Queue):
#! perl -slw
use strict;
use IO::Socket;
use threads qw[ yield ];
use threads::shared;
use Thread::Queue;
$| = 1;
our $THREADS ||= 5;
my $listening : shared = 0;
our $ios = IO::Socket::INET->new(
LocalPort => 6969,
Type => &IO::Socket::SOCK_STREAM,
Proto => 'tcp',
Reuse => 1,
Listen => 100,
) or die "IO::S->new failed with $!";
print "$ios";
sub server {
$listening++;
my( $Qquery, $Qreply ) = @_;
my $tid = threads->self->tid;
print "tid:$tid";
## Give th other threads a chance to get up and running.
yield until $listening == $THREADS;
while( my $client = $ios->accept() ) {
chomp( my $query = <$client> );
# print "$tid: $client got: '$query'";
$Qquery->enqueue( "$tid:$query" );
my $reply = $Qreply->dequeue();
print $client $reply;
close $client;
}
$listening--;
}
my @Qs = map{ new Thread::Queue } 0 .. $THREADS;
threads->new( \&server, $Qs[ 0 ], $Qs[ $_ ] )->detach for 1 .. $THREAD
+S;
yield until $listening == $THREADS;
print "Threads $listening running; grabbing data";
open BIGFILE, '< :raw', 'data/50MB.dat' or die "data/50mb.dat: $!";
my $data;
sysread( BIGFILE, $data, -s( BIGFILE ) ) or die "sysread BIGFILE : $!"
+;
close BIGFILE;
while( $listening ) {
my( $tid, $msg ) = split ':', $Qs[ 0 ]->dequeue();
## Process request
print "Received '$msg' from $tid";
$Qs[ $tid ]->enqueue( 'Thankyou for your enquiry' );
}
Partial server log
__END__
P:\test>388547 -THREADS=10
IO::Socket::INET=GLOB(0x197f1ac)
tid:1
tid:2
tid:3
tid:4
tid:5
tid:6
tid:9
tid:8
tid:7
tid:10
Threads 10 running; grabbing data
Received 'Why don't you call me anymore?' from 10
Received 'Why don't you call me anymore?' from 1
Received 'Why don't you call me anymore?' from 2
Received 'Why don't you call me anymore?' from 3
Received 'Why don't you call me anymore?' from 4
Received 'Why don't you call me anymore?' from 5
Received 'Why don't you call me anymore?' from 6
Received 'Why don't you call me anymore?' from 9
Received 'Why don't you call me anymore?' from 8
Received 'Why don't you call me anymore?' from 7
Received 'Why don't you call me anymore?' from 10
Received 'Why don't you call me anymore?' from 1
Received 'Why don't you call me anymore?' from 2
Received 'Why don't you call me anymore?' from 3
Received 'Why don't you call me anymore?' from 4
Received 'Why don't you call me anymore?' from 5
Received 'Why don't you call me anymore?' from 6
Received 'Why don't you call me anymore?' from 9
Received 'Why don't you call me anymore?' from 8
Received 'Why don't you call me anymore?' from 7
Received 'Why don't you call me anymore?' from 10
Received 'Why don't you call me anymore?' from 1
Received 'Why don't you call me anymore?' from 2
Received 'Why don't you call me anymore?' from 3
Received 'Why don't you call me anymore?' from 4
Received 'Why don't you call me anymore?' from 5
Received 'Why don't you call me anymore?' from 6
Received 'Why don't you call me anymore?' from 9
Client:
#! perl -slw
use strict;
use IO::Socket;
my $socket = IO::Socket::INET->new(
PeerAddr => '127.0.0.1',
PeerPort => 6969,
Proto => "tcp",
Type => SOCK_STREAM
) or die "Couldn't connect to 127.0.0.1:6969 : $@";
# ... do something with the socket
print $socket "Why don't you call me anymore?";
chomp( my $answer = <$socket> );
print "Got: $answer";
# and terminate the connection when we're done
close($socket);
__END__
for /l %i in (1,1,30) do @start /b SockClient
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
P:\test>Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
Got: Thankyou for your enquiry
As is, the server doesn't contain any mechanism for shutting it down, but ^C works okay and a SIGINT handler could deal with cleanup if required.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon