summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-01-26 10:00:39 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-01-26 10:00:39 (GMT)
commite360d9507a698290484f2d6b2ff7941db3d30045 (patch)
treedadbf3513af3ebcf903c50ae70b39b919d5c6cb0 /Lib
parent85e2e4742d0a1accecd02058a7907df36308297e (diff)
downloadcpython-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 'Lib')
-rw-r--r--Lib/random.py51
1 files changed, 45 insertions, 6 deletions
diff --git a/Lib/random.py b/Lib/random.py
index a22449c..baebdf0 100644
--- a/Lib/random.py
+++ b/Lib/random.py
@@ -25,12 +25,51 @@
Translated from anonymously contributed C/C++ source.
-Multi-threading note: the random number generator used here is not
-thread-safe; it is possible that two calls return the same random
-value. But you can instantiate a different instance of Random() in
-each thread to get generators that don't share state, then use
-.setstate() and .jumpahead() to move the generators to disjoint
-segments of the full period.
+Multi-threading note: the random number generator used here is not thread-
+safe; it is possible that two calls return the same random value. However,
+you can instantiate a different instance of Random() in each thread to get
+generators that don't share state, then use .setstate() and .jumpahead() to
+move the generators to disjoint segments of the full period. For example,
+
+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)
+
+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 g.random() more than a million
+times (the second argument to create_generators), the sequences seen by
+each thread will not overlap.
+
+The period of the underlying Wichmann-Hill generator is 6,953,607,871,644,
+and that limits how far this technique can be pushed.
+
+Just for fun, note that since we know the period, .jumpahead() can also be
+used to "move backward in time":
+
+>>> g = Random(42) # arbitrary
+>>> g.random()
+0.24855401895528142
+>>> g.jumpahead(6953607871644L - 1) # move *back* one
+>>> g.random()
+0.24855401895528142
"""
# XXX The docstring sucks.