Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: Handling multiple clients (use threads)

by BrowserUk (Patriarch)
on Sep 05, 2004 at 11:50 UTC ( [id://388592]=note: print w/replies, xml ) Need Help??


in reply to Handling multiple clients

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

Replies are listed 'Best First'.
Re^2: Handling multiple clients (use threads)
by jalewis2 (Monk) on Sep 05, 2004 at 21:16 UTC
    Thanks to everyone that replied. I think I misunderstood what exactly the fork was doing in relation to what I wanted to accomplish.

    I am going to give BroswerUK's code a try.

    Thanks again for the quick response.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://388592]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-04-24 00:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found