in reply to Problems with a thread-pooled tcp server

Moving the example scripts here since it was spamming the main page, sorry :)

The RCVR_MAXCON variable in the example script is set to 3 to make this happen much quicker.

#!/usr/bin/perl -w use strict; use threads; use threads::shared; use IO::Socket; my $RCVR_MAXCON = 3; # Max connections a receiver will process before +recycling my $MAXRCVR = 50; # Hard max limit my $MINIDLE = 5; # Minimum idle threads my $MAXIDLE = 10; # Maximum idle threads # Shared receiver thread status hash my %idle : shared; my %busy : shared; my $statchg : shared = 1; # change status sub setidle { my $tid = threads->self->tid; lock($statchg); delete $busy{$tid}; $idle{$tid} = 1; $statchg++; cond_signal($statchg); } sub setbusy { my $tid = threads->self->tid; lock($statchg); delete $idle{$tid}; $busy{$tid} = 1; $statchg++; cond_signal($statchg); } sub setdead { my $tid = threads->self->tid; lock($statchg); delete $idle{$tid}; delete $busy{$tid}; $statchg++; cond_signal($statchg); } sub receiver($) { my $lsock = shift; my $runcount = $RCVR_MAXCON; threads->self->detach; while($runcount > 0) { my $data; my $temp; setidle; my $conn = $lsock->accept; setbusy; while($conn->read($temp,16384)) { $data.=$temp; } print "Thread " . threads->self->tid . " received $data\n"; $conn->close(); $runcount--; } print "+++Thread " . threads->self->tid . " exiting after $RCVR_MAXC +ON connections\n"; $lsock->close; setdead; } # Create the tcp socket; my $lsock = IO::Socket::INET->new ( Listen => 10, LocalPort => 7676, Proto => 'tcp', Reuse => 1 ) || die $!; while (1) { lock($statchg); cond_wait($statchg) until $statchg > 0; my $idlecount = scalar(keys %idle); my $busycount = scalar(keys %busy); my $total = $idlecount+$busycount; print "--Current-- Idle: $idlecount Busy: $busycount\n"; if($total < $MAXRCVR && $idlecount < $MINIDLE) { print "--------- Adding 1 thread!\n"; threads->create("receiver",$lsock) || die $!; } elsif($idlecount > $MAXIDLE) { print "--------- Killing 1 thread!\n"; # kill 1 thread, unimplemented yet... } $statchg=0; }
And here's a client script I use to stuff some connections at the server. I usually just fire off several in the background like: ./testclient & ./testclient & ./testclient &
#!/usr/bin/perl -w use strict; use IO::Socket; while(my $sock = IO::Socket::INET->new("localhost:7676")) { print $sock "TEST"; sleep 1; $sock->close; }

Replies are listed 'Best First'.
Re^2: Problems with a thread-pooled tcp server
by BrowserUk (Patriarch) on Jan 13, 2005 at 19:35 UTC

    FYI: Your code appears to function as designed, without errors, when run under 5.8.5 and win32.

    I think dave_the_m called it right when he suggested you upgrade. Threads were still quite flakey in 5.8.1.

    Is there a particular reason for using a single scalar to guard both your shared hashes rather than locking the hash itself (or the element being accessed) individually?


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.