Multitasking Server with Threads (Perl Cookbook, 2nd Edition)

## 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 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. 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 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 Also

The documentation for the standard module threads.pm; Recipe 17.15

Copyright © 2003 O'Reilly & Associates. All rights reserved.