[ Team LiB ] |
Recipe 17.14 Multitasking Server with Threads17.14.1 ProblemYou want to write a server that handles multiple clients from within the one process using your operating system's threads. 17.14.2 SolutionUse Perl v5.8.1 or later and threads.pm: use threads; use IO::Socket; my $listen = IO::Socket::INET->new( LocalPort => $SERVER_PORT, ReuseAddr => 1, Listen => 10, ); sub handle_connection { my $socket = shift; my $output = shift || $socket; my $exit = 0; while (<$socket>) { # work with $_, # print to $output # set $exit to true when connection is done last if $exit; } } while (my $socket = $listen->accept) { async(\&handle_connection, $socket)->detach; } 17.14.3 DiscussionThreading in Perl is still evolving, but it became functional as of v5.8.1. The code in the Solution will not work in earlier versions of Perl. In particular, earlier versions of Perl implemented an entirely different threading model than the current "interpreter threads" system that threads.pm assumes. The hard work of handling the connection to the client is done in the handle_connection subroutine. It is given the client socket as a parameter, and can call blocking routines like <$socket> because it runs in its own thread. If one thread blocks while reading, other threads can still run. The master thread in the program creates the socket and accepts connections on it. When a new client connects, the master thread spawns a new thread (with the async call) to handle the connection. The thread runs until the subroutine it is called with (handle_connection in this case) returns. We detach the newly created thread to ensure that its variables are garbage collected (closing the socket to the client) when the thread ends. If we didn't call detach, our process would accumulate dead threads until we could no longer spawn new threads. 17.14.4 See AlsoThe documentation for the standard module threads.pm; Recipe 17.15 |
[ Team LiB ] |