Hello Folks:

Enclosed is a new version of pickle-sieve. I took Andrew Dalke's
advice (it is good advice) and changed the following code

def counter(c):
    i = 2
    while (True):
        c.send(i)
        i += 1

to 

def counter(c):
    for i in itertools.count(2):
        c.send(i)

when I hit control C, I get the following error:

Traceback (most recent call last):
  File "pickle-sieve-new.py", line 110, in <module>
    pickle.dump(image, fd)
  File "/usr/local/lib/python2.6/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle count objects

Is this meant to so?

Cheers,
Andrew


      
import cPickle as pickle
import stackless
import sys
import signal
import itertools

"""
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):
    for i in listen:
       if (i % prime):
          send.send(i)

       
def counter(c):
    for i in itertools.count(2):
        c.send(i)


def sieve(prime, c):
    global image
    for p in c:
        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(sys.argv[1], '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()
_______________________________________________
Stackless mailing list
Stackless@stackless.com
http://www.stackless.com/mailman/listinfo/stackless

Reply via email to