diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-01-26 10:00:39 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-01-26 10:00:39 (GMT) |
commit | e360d9507a698290484f2d6b2ff7941db3d30045 (patch) | |
tree | dadbf3513af3ebcf903c50ae70b39b919d5c6cb0 /Doc | |
parent | 85e2e4742d0a1accecd02058a7907df36308297e (diff) | |
download | cpython-e360d9507a698290484f2d6b2ff7941db3d30045.zip cpython-e360d9507a698290484f2d6b2ff7941db3d30045.tar.gz cpython-e360d9507a698290484f2d6b2ff7941db3d30045.tar.bz2 |
The combo of getstate/setstate/jumpahead is very powerful, but needs
examples to flesh it out for the uninitiated. Here they are.
Diffstat (limited to 'Doc')
-rw-r--r-- | Doc/lib/librandom.tex | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/Doc/lib/librandom.tex b/Doc/lib/librandom.tex index 9d303c2..d271c57 100644 --- a/Doc/lib/librandom.tex +++ b/Doc/lib/librandom.tex @@ -38,11 +38,57 @@ own instances of \var{Random} to get generators that don't share state. This is especially useful for multi-threaded programs, creating a different instance of \var{Random} for each thread, and using the \method{jumpahead()} method to ensure that the generated sequences seen by each thread don't -overlap. Class \var{Random} can also be subclassed if you want to use a -different basic generator of your own devising: in that case, override the +overlap (see example below). +Class \var{Random} can also be subclassed if you want to use a different +basic generator of your own devising: in that case, override the \method{random()}, \method{seed()}, \method{getstate()}, \method{setstate()} and \method{jumpahead()} methods. +Here's one way to create threadsafe distinct and non-overlapping generators: + +\begin{verbatim} +def create_generators(num, delta, firstseed=None): + """Return list of num distinct generators. + Each generator has its own unique segment of delta elements + from Random.random()'s full period. + Seed the first generator with optional arg firstseed (default + is None, to seed from current time). + """ + + from random import Random + g = Random(firstseed) + result = [g] + for i in range(num - 1): + laststate = g.getstate() + g = Random() + g.setstate(laststate) + g.jumpahead(delta) + result.append(g) + return result + +gens = create_generators(10, 1000000) +\end{verbatim} + +That creates 10 distinct generators, which can be passed out to 10 distinct +threads. The generators don't share state so can be called safely in +parallel. So long as no thread calls its \code{g.random()} more than a +million times (the second argument to \function{create_generators}), the +sequences seen by each thread will not overlap. The period of the +underlying Wichmann-Hill generator limits how far this technique can be +pushed. + +Just for fun, note that since we know the period, \method{jumpahead()} can +also be used to "move backward in time": + +\begin{verbatim} +>>> g = Random(42) # arbitrary +>>> g.random() +0.24855401895528142 +>>> g.jumpahead(6953607871644L - 1) # move *back* one +>>> g.random() +0.24855401895528142 +\end{verbatim} + Bookkeeping functions: |