📄 ch16_13.htm
字号:
<HTML><HEAD><TITLE>Recipe 16.12. Sharing Variables in Different Processes (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:07Z"><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="ch16_01.htm"TITLE="16. Process Management and Communication"><LINKREL="prev"HREF="ch16_12.htm"TITLE="16.11. Making a Process Look Like a File with Named Pipes"><LINKREL="next"HREF="ch16_14.htm"TITLE="16.13. Listing Available Signals"></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="ch16_12.htm"TITLE="16.11. Making a Process Look Like a File with Named Pipes"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 16.11. Making a Process Look Like a File with Named Pipes"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch16_01.htm"TITLE="16. Process Management and Communication"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch16_14.htm"TITLE="16.13. Listing Available Signals"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 16.13. Listing Available Signals"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch16-32637">16.12. Sharing Variables in Different Processes</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch16-pgfId-2148">Problem<ACLASS="indexterm"NAME="ch16-idx-1000006366-0"></A><ACLASS="indexterm"NAME="ch16-idx-1000006366-1"></A><ACLASS="indexterm"NAME="ch16-idx-1000006366-2"></A><ACLASS="indexterm"NAME="ch16-idx-1000006366-3"></A></A></H3><PCLASS="para">You want to share variables across forks or between unrelated processes.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch16-pgfId-2154">Solution</A></H3><PCLASS="para">Use SysV IPC, if your operating system supports it.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch16-pgfId-2160">Discussion</A></H3><PCLASS="para">While SysV IPC (shared memory, semaphores, etc.) isn't as widely used as pipes, named pipes, and sockets for interprocess communication, it still has some interesting properties. Normally, however, you can't expect to use shared memory via <CODECLASS="literal">shmget</CODE> or the <ICLASS="filename">mmap </I>(2) system call to share a variable among several processes. That's because Perl would reallocate your string when you weren't wanting it to.</P><PCLASS="para">The CPAN module <ACLASS="indexterm"NAME="ch16-idx-1000006367-0"></A>IPC::Shareable takes care of that. Using a clever <CODECLASS="literal">tie</CODE> module, SysV shared memory, and the Storable module from CPAN allows data structures of arbitrary complexity to be shared among cooperating processes on the same machine. These processes don't even have to be related to each other.</P><PCLASS="para"><ACLASS="xref"HREF="ch16_13.htm#ch16-25358"TITLE="sharetest">Example 16.11</A> is a simple demonstration of the module.</P><DIVCLASS="example"><H4CLASS="example"><ACLASS="title"NAME="ch16-25358">Example 16.11: sharetest</A></H4><PRECLASS="programlisting">#!/usr/bin/perl # <ACLASS="indexterm"NAME="ch16-idx-1000006368-0"></A>sharetest - test shared variables across forksuse IPC::Shareable;$handle = tie $buffer, 'IPC::Shareable', undef, { destroy => 1 };$SIG{INT} = sub { die "$$ dying\n" };for (1 .. 10) { unless ($child = fork) { # i'm the child die "cannot fork: $!" unless defined $child; squabble(); exit; } push @kids, $child; # in case we care about their pids}while (1) { print "Buffer is $buffer\n"; sleep 1;} die "Not reached";sub squabble { my $i = 0; while (1) { next if $buffer =~ /^$$\b/o; $handle->shlock(); $i++; $buffer = "$$ $i"; $handle->shunlock(); }} </PRE></DIV><PCLASS="para">The starting process creates the shared variable, forks off 10 children, and then sits back and prints out the value of the buffer every second or so, forever, or until you hit Ctrl-C.</P><PCLASS="para">Because the SIGINT handler was set before any forking, it got inherited by the squabbling children as well, so they'll also bite the dust when the process group is interrupted. Keyboard interrupts send signals to the whole process group, not just one process.</P><PCLASS="para">What do the kids squabble over? They're bickering over who gets to update that shared variable. Each one looks to see whether someone else was here or not. So long as the buffer starts with their own signature (their PID), they leave it alone. As soon as someone else has changed it, they lock the shared variable using a special method call on the handle returned from the <CODECLASS="literal">tie</CODE>, update it, and release the lock.</P><PCLASS="para">The program runs much faster by commenting out the line that starts with <CODECLASS="literal">next</CODE> where each process is checking that they were the last one to touch the buffer.</P><PCLASS="para">The <CODECLASS="literal">/^$$\b/o</CODE> may look suspicious, since <CODECLASS="literal">/o</CODE> tells Perl to compile the pattern once only, but then went and changed the variable's value by forking. Fortunately, the value isn't locked at program compile time, but only the first time the pattern is itself compiled in each process, during whose own lifetime <CODECLASS="literal">$$</CODE> does not alter.</P><PCLASS="para">The IPC::Sharable module also supports sharing variables among unrelated processes on the same machine. See its documentation for details.<ACLASS="indexterm"NAME="ch16-idx-1000008779-0"></A><ACLASS="indexterm"NAME="ch16-idx-1000008779-1"></A><ACLASS="indexterm"NAME="ch16-idx-1000008779-2"></A><ACLASS="indexterm"NAME="ch16-idx-1000008779-3"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch16-pgfId-1000008287">See Also</A></H3><PCLASS="para">The <ACLASS="olink"HREF="../prog/ch03_136.htm"><CODECLASS="literal">semctl</CODE></A>, <ACLASS="olink"HREF="../prog/ch03_137.htm"><CODECLASS="literal">semget</CODE></A>, <ACLASS="olink"HREF="../prog/ch03_138.htm"><CODECLASS="literal">semop</CODE></A>, <ACLASS="olink"HREF="../prog/ch03_136.htm"><CODECLASS="literal">shmctl</CODE></A>, <ACLASS="olink"HREF="../prog/ch03_137.htm"><CODECLASS="literal">shmget</CODE></A>, <ACLASS="olink"HREF="../prog/ch03_146.htm"><CODECLASS="literal">shmread</CODE></A>, and <ACLASS="olink"HREF="../prog/ch03_147.htm"><CODECLASS="literal">shmwrite</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 <EMCLASS="emphasis">perlfunc </EM>(1); the documentation for the IPC::Shareable module from CPAN</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="ch16_12.htm"TITLE="16.11. Making a Process Look Like a File with Named Pipes"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 16.11. Making a Process Look Like a File with Named Pipes"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="ch16_14.htm"TITLE="16.13. Listing Available Signals"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 16.13. Listing Available Signals"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">16.11. Making a Process Look Like a File with Named Pipes</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">16.13. Listing Available Signals</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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -