Hi Folks:
I recently did a talk at the Montreal Python user's group. To illustrate the
power of Stackless, I adapted Robert Pike's prime number sieve written in
Newsqueak for Stackless Python (I was inspired by the Gregario PyCSP example).
Like my previous talk, I got requests from people to see pickling examples (it
seems to be an eye opener). So I wrote a version of the sieve that can be
pickled and resumed. In this fashion, hundred of thousands of primes can be
generated at one's leisure. I have executed the programme in both pypy-c and
Stackless Python. I would appreciate comments before putting it in the
Stackless repository (however I do that).
Cheers,
Andrew
import cPickle as pickle
import stackless
import sys
import signal
"""
pickled-sieve.py
Andrew Francis
October 30th, 2009
pickled-sieve.py is an implementation of the Sieve of Eratosthenes
with a twist: when Control-C is pressed, all the tasklets (one for each
prime) and associated channels are pickled to a file sieve.dat.
in the future, if pickle-sieve.py is executed with a file name:
$python pickle-sieve.py sieve.dat
provided the file format is correct, all the tasklets and their associated
channels are deserialised and the programme resumes where it left off. This
is a good way of computing thousands of primes over multiple sessions and
on different machines.
<song> Almost Crimes - Broken Social Scene</song>
"""
flag = False
"""
we want to do the serialisation in the main tasklet's loop
"""
def signalHandler(signal, frame):
global flag
flag = True
"""
image is used to stores tasklets and their associated channels. The
channels are serialised separately because when a blocked tasklet is
serialised, the channel is not included.
"""
class Image(object):
def __init__(self):
self.channels = []
self.tasklets = []
# record tasklets
def makeTasklet(self, f, *args, **kwargs):
t = stackless.tasklet(f)(*args, **kwargs)
self.tasklets.append(t)
return t
# record channels
def makeChannel(self):
channel = stackless.channel()
self.channels.append(channel)
return channel
"""
the sieve proper
"""
def filter(prime, listen, send):
while (True):
i = listen.receive()
if (i % prime):
send.send(i)
def counter(c):
i = 2
while (True):
c.send(i)
i += 1
def sieve(prime, c):
global image
while (True):
p = c.receive()
prime.send(p)
newc = image.makeChannel()
image.makeTasklet(filter, p, c, newc)
c = newc
if __name__ == "__main__":
signal.signal(signal.SIGINT, signalHandler)
if len(sys.argv) == 2:
fd = open('sieve.dat', 'r')
image = pickle.load(fd)
for t in image.tasklets:
"""
we have to make sure that we are not inserting tasklets that
were blocked.
"""
if not t.blocked:
t.insert()
stackless.schedule()
else:
image = Image()
image.makeChannel()
image.makeChannel()
image.makeTasklet(counter, image.channels[1])
image.makeTasklet(sieve, image.channels[0], image.channels[1])
while(True):
if (flag):
fd = open('sieve.dat','w')
pickle.dump(image, fd)
fd.close()
print "pickled ", len(image.tasklets),"and ", len(image.channels)
break
else:
print image.channels[0].receive()
_______________________________________________
[email protected]
http://codespeak.net/mailman/listinfo/pypy-dev