ch17_12.htm
来自「By Tom Christiansen and Nathan Torkingto」· HTM 代码 · 共 441 行
HTM
441 行
<HTML><HEAD><TITLE>Recipe 17.11. Forking Servers (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:44:36Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch17_01.htm"TITLE="17. Sockets"><LINKREL="prev"HREF="ch17_11.htm"TITLE="17.10. Writing Bidirectional Clients"><LINKREL="next"HREF="ch17_13.htm"TITLE="17.12. Pre-Forking Servers"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch17_11.htm"TITLE="17.10. Writing Bidirectional Clients"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 17.10. Writing Bidirectional Clients"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch17_01.htm"TITLE="17. Sockets"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch17_13.htm"TITLE="17.12. Pre-Forking Servers"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 17.12. Pre-Forking Servers"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch17-41561">17.11. Forking Servers</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch17-pgfId-1224">Problem<ACLASS="indexterm"NAME="ch17-idx-1000004806-0"></A><ACLASS="indexterm"NAME="ch17-idx-1000004806-1"></A><ACLASS="indexterm"NAME="ch17-idx-1000004806-2"></A></A></H3><PCLASS="para">You want to write a server that forks a subprocess to handle each new client.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch17-pgfId-1230">Solution</A></H3><PCLASS="para">Fork in the <CODECLASS="literal">accept</CODE> loop, and use a <CODECLASS="literal">$SIG{CHLD}</CODE> handler to reap the children.</P><PRECLASS="programlisting"># set up the socket SERVER, bind and listen ...use POSIX qw(:sys_wait_h);sub REAPER { 1 until (-1 == waitpid(-1, WNOHANG)); $SIG{CHLD} = \&REAPER; # unless $] >= 5.002}$SIG{CHLD} = \&REAPER;while ($hisaddr = accept(CLIENT, SERVER)) { next if $pid = fork; # parent die "fork: $!" unless defined $pid; # failure # otherwise child close(SERVER); # no use to child # ... do something exit; # child leaves} continue { close(CLIENT); # no use to parent}</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch17-pgfId-1274">Discussion</A></H3><PCLASS="para"><ACLASS="indexterm"NAME="ch17-idx-1000004821-0"></A>This approach is very common for SOCK_STREAM servers in the Internet and Unix domains. Each incoming connection gets a cloned server of its own. The model is:</P><OLCLASS="orderedlist"><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch17-pgfId-1278"></A>Accept a stream connection.</P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch17-pgfId-1280"></A>Fork off a duplicate to communicate over that stream.</P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch17-pgfId-1282"></A>Return to 1.</P></LI></OL><PCLASS="para">This technique isn't used with SOCK_DGRAM sockets because their method of communication is different. The time it takes to fork makes the forking model impractical for UDP-style servers. Instead of working with a series of stateful, long-running connections, SOCK_DGRAM servers work with a bunch of sporadic datagrams, usually statelessly. With them, the model must become:</P><OLCLASS="orderedlist"><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch17-pgfId-1286"></A>Read a datagram.</P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch17-pgfId-1288"></A>Handle the datagram.</P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch17-pgfId-1290"></A>Return to 1.</P></LI></OL><PCLASS="para">The child process deals with the new connection. Because it will never use the SERVER socket, we immediately close it. This is partly to keep a tidy house, but mainly so that the server socket is closed when the parent (server) process exits. If the children do not close the SERVER socket, the operating system considers the socket still open even when the parent dies. For more on this, see <ACLASS="xref"HREF="ch17_10.htm"TITLE="Closing a Socket After Forking">Recipe 17.9</A>.</P><PCLASS="para"><CODECLASS="literal">%SIG</CODE> ensures that we clean up after our children when they exit. See <ACLASS="xref"HREF="ch16_01.htm"TITLE="Process Management and Communication">Chapter 16, <CITECLASS="chapter">Process Management and Communication</CITE></A> for details.<ACLASS="indexterm"NAME="ch17-idx-1000004817-0"></A><ACLASS="indexterm"NAME="ch17-idx-1000004817-1"></A><ACLASS="indexterm"NAME="ch17-idx-1000004817-2"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch17-pgfId-1298">See Also</A></H3><PCLASS="para">The <ACLASS="olink"HREF="../prog/ch03_040.htm"> <CODECLASS="literal">fork</CODE></A> and <ACLASS="olink"HREF="../prog/ch03_004.htm"> <CODECLASS="literal">accept</CODE></A> functions in <ACLASS="olink"HREF="../prog/ch03_01.htm">Chapter 3</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A> and in <ICLASS="filename">perlfunc </I>(1); <ACLASS="xref"HREF="ch16_16.htm"TITLE="Installing a Signal Handler">Recipe 16.15</A>; <ACLASS="xref"HREF="ch16_20.htm"TITLE="Avoiding Zombie Processes">Recipe 16.19</A>; <ACLASS="xref"HREF="ch17_13.htm"TITLE="Pre-Forking Servers">Recipe 17.12</A>; <ACLASS="xref"HREF="ch17_14.htm"TITLE="Non-Forking Servers">Recipe 17.13</A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch17_11.htm"TITLE="17.10. Writing Bidirectional Clients"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 17.10. Writing Bidirectional Clients"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch17_13.htm"TITLE="17.12. Pre-Forking Servers"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 17.12. Pre-Forking Servers"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">17.10. Writing Bidirectional Clients</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">17.12. Pre-Forking Servers</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?