Recipe 17.14 Multitasking Server with Threads

17.14.1 Problem

You want to write a server that handles multiple clients from within the one process using your operating system's threads.

17.14.2 Solution

Use Perl v5.8.1 or later and

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 Discussion

Threading 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 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 Also

The documentation for the standard module; Recipe 17.15