By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998

源代码在线查看: ch17_13.htm

软件大小: 1747 K
上传用户: tiandl
关键词: Christiansen Torkington published Edition
下载地址: 免注册下载 普通下载 VIP

相关代码

								>				>				Recipe 17.12. Pre-Forking Servers (Perl Cookbook)								NAME="DC.title"				CONTENT="Perl Cookbook">				NAME="DC.creator"				CONTENT="Tom Christiansen & Nathan Torkington">				NAME="DC.publisher"				CONTENT="O'Reilly & Associates, Inc.">				NAME="DC.date"				CONTENT="1999-07-02T01:44:41Z">				NAME="DC.type"				CONTENT="Text.Monograph">				NAME="DC.format"				CONTENT="text/html"				SCHEME="MIME">				NAME="DC.source"				CONTENT="1-56592-243-3"				SCHEME="ISBN">				NAME="DC.language"				CONTENT="en-US">				NAME="generator"				CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0">				REV="made"				HREF="mailto:online-books@oreilly.com"				TITLE="Online Books Comments">				REL="up"				HREF="ch17_01.htm"				TITLE="17. Sockets">				REL="prev"				HREF="ch17_12.htm"				TITLE="17.11. Forking Servers">				REL="next"				HREF="ch17_14.htm"				TITLE="17.13. Non-Forking Servers">				>				BGCOLOR="#FFFFFF">								WIDTH="684"				BORDER="0"				CELLSPACING="0"				CELLPADDING="0"				>				>				ALIGN="LEFT"				VALIGN="TOP"				WIDTH="228"				>				CLASS="sect1"				HREF="ch17_12.htm"				TITLE="17.11. Forking Servers"				>				SRC="../gifs/txtpreva.gif"				ALT="Previous: 17.11. Forking Servers"				BORDER="0">				>				>				ALIGN="CENTER"				VALIGN="TOP"				WIDTH="228"				>				>				FACE="ARIEL,HELVETICA,HELV,SANSERIF"				SIZE="-1"				>				CLASS="chapter"				REL="up"				HREF="ch17_01.htm"				TITLE="17. Sockets"				>				>				>				>				>				ALIGN="RIGHT"				VALIGN="TOP"				WIDTH="228"				>				CLASS="sect1"				HREF="ch17_14.htm"				TITLE="17.13. Non-Forking Servers"				>				SRC="../gifs/txtnexta.gif"				ALT="Next: 17.13. Non-Forking Servers"				BORDER="0">				>				>				>				>				>				CLASS="sect1"				>				CLASS="sect1"				>				CLASS="title"				NAME="ch17-19439"				>17.12. Pre-Forking Servers				>				>				CLASS="sect2"				>				CLASS="sect2"				>				CLASS="title"				NAME="ch17-pgfId-1308"				>Problem				>				>				CLASS="para"				>				CLASS="indexterm"				NAME="ch17-idx-1000004828-0"				>				>				CLASS="indexterm"				NAME="ch17-idx-1000004828-1"				>				>				CLASS="indexterm"				NAME="ch17-idx-1000004828-2"				>				>				CLASS="indexterm"				NAME="ch17-idx-1000004828-3"				>				>You want to write a server that concurrently processes several clients (as in "Forking Servers"), but connections are coming in so fast that forking slows the server too much.				>				>				CLASS="sect2"				>				CLASS="sect2"				>				CLASS="title"				NAME="ch17-pgfId-1314"				>Solution				>				>				CLASS="para"				>Have a master server maintain a pool of pre-forked children, as shown in 				CLASS="xref"				HREF="ch17_13.htm#ch17-30092"				TITLE="preforker"				>Example 17.5				>.				>				CLASS="example"				>				CLASS="example"				>				CLASS="title"				NAME="ch17-30092"				>Example 17.5: preforker				>				>				CLASS="programlisting"				>#!/usr/bin/perl				# 				CLASS="indexterm"				NAME="ch17-idx-1000004832-0"				>				>preforker - server who forks first				use IO::Socket;				use Symbol;				use POSIX;								# establish SERVER socket, bind and listen.				$server = IO::Socket::INET->new(LocalPort => 6969,				                                Type      => SOCK_STREAM,				                                Proto     => 'tcp',				                                Reuse     => 1,				                                Listen    => 10 )				  or die "making socket: $@\n";								# global variables				$PREFORK                = 5;        # number of children to maintain				$MAX_CLIENTS_PER_CHILD  = 5;        # number of clients each child should process				%children               = ();       # keys are current child process IDs				$children               = 0;        # current number of children								sub REAPER {                        # takes care of dead children				    $SIG{CHLD} = \&REAPER;				    my $pid = wait;				    $children --;				    delete $children{$pid};				}								sub HUNTSMAN {                      # signal handler for SIGINT				    local($SIG{CHLD}) = 'IGNORE';   # we're going to kill our children				    kill 'INT' => keys %children;				    exit;                           # clean up with dignity				}				    				# Fork off our children.				for (1 .. $PREFORK) {				    make_new_child();				}								# Install signal handlers.				$SIG{CHLD} = \&REAPER;				$SIG{INT}  = \&HUNTSMAN;								# And maintain the population.				while (1) {				    sleep;                          # wait for a signal (i.e., child's death)				    for ($i = $children; $i < $PREFORK; $i++) {				        make_new_child();           # top up the child pool				    }				}								sub make_new_child {				    my $pid;				    my $sigset;				    				    # block signal for fork				    $sigset = POSIX::SigSet->new(SIGINT);				    sigprocmask(SIG_BLOCK, $sigset)				        or die "Can't block SIGINT for fork: $!\n";				    				    die "fork: $!" unless defined ($pid = fork);				    				    if ($pid) {				        # Parent records the child's birth and returns.				        sigprocmask(SIG_UNBLOCK, $sigset)				            or die "Can't unblock SIGINT for fork: $!\n";				        $children{$pid} = 1;				        $children++;				        return;				    } else {				        # Child can *not* return from this subroutine.				        $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before				    				        # unblock signals				        sigprocmask(SIG_UNBLOCK, $sigset)				            or die "Can't unblock SIGINT for fork: $!\n";				    				        # handle connections until we've reached $MAX_CLIENTS_PER_CHILD				        for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {				            $client = $server->accept()     or last;				            # do something with the connection				        }				    				        # tidy up gracefully and finish				    				        # this exit is VERY important, otherwise the child will become				        # a producer of more and more children, forking yourself into				        # process death.				        exit;				    }				}				>				>				>				CLASS="sect2"				>				CLASS="sect2"				>				CLASS="title"				NAME="ch17-pgfId-1502"				>Discussion				>				>				CLASS="para"				>Whew. Although this is a lot of code, the logic is simple: the parent process never deals with clients but instead forks 				CLASS="literal"				>$PREFORK				> children to do that. The parent keeps track of how many children it has and forks more to replace dead children. Children exit after having handled 				CLASS="literal"				>$MAX_CLIENTS_PER_CHILD				> clients.				>				CLASS="para"				>The code is a reasonably direct implementation of the logic above. The only trick comes with signal handlers: we want the parent to catch SIGINT and kill its children, so we install our signal handler 				CLASS="literal"				>&HUNTSMAN				> to do this. But we then have to be careful that the child doesn't have the same handler after we fork. We use POSIX signals to block the signal for the duration of the fork (see 				CLASS="xref"				HREF="ch16_21.htm"				TITLE="Blocking Signals"				>Recipe 16.20				>).				>				CLASS="para"				>When you use this code in your programs, be sure that 				CLASS="literal"				>make_new_child				> never returns. If it does, the child will return, become a parent, and spawn off its own children. Your system will fill up with processes, your system administrator will storm down the hallway to find you, and you may end up tied to four horses wondering why you hadn't paid more attention to this paragraph.				>				CLASS="para"				>On some operating systems, notably Solaris, you cannot have multiple children doing an 				CLASS="literal"				>accept				> on the same socket. You have to use file locking to ensure that only one child can call 				CLASS="literal"				>accept				> at any particular moment.				CLASS="indexterm"				NAME="ch17-idx-1000004834-0"				>				>				CLASS="indexterm"				NAME="ch17-idx-1000004834-1"				>				>				CLASS="indexterm"				NAME="ch17-idx-1000004834-2"				>				>				CLASS="indexterm"				NAME="ch17-idx-1000004834-3"				>				>				>				>				CLASS="sect2"				>				CLASS="sect2"				>				CLASS="title"				NAME="ch17-pgfId-1514"				>See Also				>				>				CLASS="para"				>The 								CLASS="olink"				HREF="../prog/ch03_135.htm"				>
								CLASS="literal"				>select				>				> function in 								CLASS="olink"				HREF="../prog/ch03_01.htm"				>
Chapter 3				> or 				CLASS="filename"				>perlfunc 				>(1); your system's 				CLASS="filename"				>fcntl 				>(2) manpage (if you have one); the documentation for the standard Fcntl, Socket, IO::Select, IO::Socket, and Tie::RefHash modules; 				CLASS="xref"				HREF="ch17_12.htm"				TITLE="Forking Servers"				>Recipe 17.11				>; 				CLASS="xref"				HREF="ch17_13.htm"				TITLE="Pre-Forking Servers"				>Recipe 17.12				>				>				>				>				CLASS="htmlnav"				>				>				>				ALIGN="LEFT"				WIDTH="684"				TITLE="footer">				WIDTH="684"				BORDER="0"				CELLSPACING="0"				CELLPADDING="0"				>				>				ALIGN="LEFT"				VALIGN="TOP"				WIDTH="228"				>				CLASS="sect1"				HREF="ch17_12.htm"				TITLE="17.11. Forking Servers"				>				SRC="../gifs/txtpreva.gif"				ALT="Previous: 17.11. Forking Servers"				BORDER="0">				>				>				ALIGN="CENTER"				VALIGN="TOP"				WIDTH="228"				>				CLASS="book"				HREF="index.htm"				TITLE="Perl Cookbook"				>				SRC="../gifs/txthome.gif"				ALT="Perl Cookbook"				BORDER="0">				>				>				ALIGN="RIGHT"				VALIGN="TOP"				WIDTH="228"				>				CLASS="sect1"				HREF="ch17_14.htm"				TITLE="17.13. Non-Forking Servers"				>				SRC="../gifs/txtnexta.gif"				ALT="Next: 17.13. Non-Forking Servers"				BORDER="0">				>				>				>				>				ALIGN="LEFT"				VALIGN="TOP"				WIDTH="228"				>17.11. Forking Servers				>				ALIGN="CENTER"				VALIGN="TOP"				WIDTH="228"				>				CLASS="index"				HREF="index/index.htm"				TITLE="Book Index"				>				SRC="../gifs/index.gif"				ALT="Book Index"				BORDER="0">				>				>				ALIGN="RIGHT"				VALIGN="TOP"				WIDTH="228"				>17.13. Non-Forking Servers				>				>				>				ALIGN="LEFT"				WIDTH="684"				TITLE="footer">				SIZE="-1"				>				>				>							

相关资源