<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Brian Phillips</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/brian_phillips/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/brian_phillips/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/brian_phillips//37</id>
    <updated>2010-06-30T16:44:02Z</updated>
    <subtitle>A blog about the Perl programming language</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>When rand isn&apos;t random</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/brian_phillips/2010/06/when-rand-isnt-random.html" />
    <id>tag:blogs.perl.org,2010:/users/brian_phillips//37.689</id>

    <published>2010-06-30T17:30:05Z</published>
    <updated>2010-06-30T16:44:02Z</updated>

    <summary>In spite of having programming Perl mostly full time for the last 12 years, I still find myself learning new things about how Perl works (like the time I discovered the arcane apostrophe package separator when trying to add a...</summary>
    <author>
        <name>Brian Phillips</name>
        <uri>http://brianphillips.emurse.com/</uri>
    </author>
    
    <category term="bugrandsrandforkmod_perl" label="bug rand srand fork mod_perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/brian_phillips/">
        <![CDATA[<p>In spite of having programming Perl mostly full time for the last 12 years, I still find myself learning new things about how Perl works (like the time I discovered the arcane <a href="http://perldoc.perl.org/perldata.html">apostrophe package separator</a> when trying to add a <a href="http://en.wikipedia.org/wiki/Possessive_s">possessive 's'</a> on the end of a variable in an interpolated string).</p>

<p>Yesterday yielded a similar epiphany when I realized how rand, srand and fork were interacting in our e-commerce application at $work.  Consider the following one-liner:</p>

<pre><code>perl -le 'for(1..2) { fork or do { print int rand 100; exit } }'</code></pre>

<p>This prints two random numbers between 0 and 99.  Simple.  Now, consider this slightly different example:</p>

<pre><code>perl -le 'rand; for(1..2) { fork or do { print int rand 100; exit } }'</code></pre>

<p>This prints the <em>same</em> random number between 0 and 99 <em>twice</em>.  The reasoning is quite simple but was not obvious to me at first.  When <code>rand</code> is first called in a Perl application, <code>srand</code> is implicitly called to seed <code>rand</code> with a different starting number.  If this happens prior to a process forking, the same seed is shared by all of the child processes and non-randomness ensues.</p>

<p>The tricky bit to this issue is that since the <code>rand</code> seed is effectively global, a pre-fork <code>rand</code> call can be anywhere in your large-ish legacy mod_perl application and it won't be apparent for quite some time why the "random" numbers being generated by the mod_perl children seem to be colliding at an alarming rate!  This issue was further occluded by the fact that the <a href="http://perldoc.perl.org/functions/srand.html">srand perldoc</a> <em>assures</em> the reader (I'm a very trusting reader) that most applications never need to call <code>srand</code> explicitly.</p>

<p>In my opinion, one of two things should be changed about how this works.  Either:</p>


<ol>
<li>The global has-rand-been-seeded flag should be per-process, or</li>
<li>A warning should be added to the <a href="http://perldoc.perl.org/functions/srand.html">srand perldoc</a> page</li>
</ol>



<p>In our case, simply adding a <code>PerlChildInitHandler</code> that re-calls <code>srand</code> proved to be a very simple fix.  This solution comes courtesy of <a href="http://marc.info/?l=apache-modperl&amp;m=123904225030744&amp;w=1">bugzilla</a> which was quite google-able once one gets past the denial and realizes that <code>fork</code> and <code>srand</code> interact differently than one thought:</p>

<pre><code># In your Apache configuration
PerlChildInitHandler &quot;sub { srand }&quot;</code></pre>

<p>What do you think?  Is this worthy of an <code>srand</code> doc patch or a functionality change or am I the last Perl developer to uncover this behavior?</p>]]>
        
    </content>
</entry>

</feed>
