Re: New stackless proposal
Lenard Lindstrom <[email protected]>
| Newsgroups | gmane.comp.lang.prothon.user |
|---|---|
| Message-ID | <Mahogany-0.66.0-4294528931-20040710-135441.00@pop3.norton.antivirus> |
On Thu, 8 Jul 2004 15:03:08 -0700 Mark Hahn <[email protected]> wrote: > http://prothon.org/wiki?pagename=StacklessLanguageFeatures > If a prothon thread must be declared using a "defInit" or "after" section of a function definition then there is no need for an "thread" keyword. Prothon thread declarations will likely outnumber OS thread declarations, especially when generators are prothon threads. So a "thread" statement that creates OS thread objects is not much of a convenience. The yield statement/function need not be a direct ThreadMgr method invocation. Simply define a built-in function as follows: def yield(value=None, to=otherThread): # what is otherThread? return curThreadMgr.yield(value, to) Having yield somehow know that it is on the right of an assignement is quirky given this feature shows up nowhere else in the language. Instead I using the "to" parameter to determine whether of not a yield is a send or receive. Define yield's paramenters as follows: (value=None, to=None) When "to" is specified then the yield is a send; when to is None, the default, the yield is a receive. If it is desired to use a thread manager as a pool of server threads then a ThreadMgr.AnyThread() method can be used as the yield's "to" argument to allow a message to be sent to the next free thread in the pool, or a randomly chosen thread for a simulation. I do not know about the empty yield case. Usually this is handled with a sleep(0) in other languages. Or the ThreadMgr prototype can have a special method for this case. It will not occur often. Summing up, an OS thread declaration: def thread1(seconds): defInit: thread1 = OSThread(thread1) print("thread1 is running") Sleep(seconds * 1.0) print("thread1 is stopping") A prothon thread: def thread1(seconds): defInit: thread1 = Thread(thread1) print("thread1 is running") Sleep(seconds * 1.0) print("thread1 is stopping") A generator: def genOdd(n): defInit: genOdd = Thread(genOdd) for i in n: if i % 2: yield(i) Finally, this is how I defined a Tasklet generator class in Stackless Python along with an example usage. Note that special care was taken to handle the case where the generator function never does a yield: import stackless class Iterator(object): def __init__(self, *args, **kwds): self.isfinished = False self.nextitem = stackless.channel() def taskbody(*args, **kwds): self.body(*args, **kwds) self.nextitem.send_exception(StopIteration) self.task = stackless.tasklet(taskbody) self.task.setup(*args, **kwds) self.task.run() def body(self, *args, **kwds): return def Yield(self, value): self.nextitem.send(value) def __iter__(self): return self def next(self): if self.isfinished: raise StopIteration try: return self.nextitem.receive() except StopIteration: self.isfinished = True raise class Fib(Iterator): def body(self, n): sum, prev = 1, 0 for i in range(n): self.Yield(sum) sum, prev = sum + prev, sum if __name__ == '__main__': # Does at least 1 yield for f in Fib(7): print f # Special case: no yield for f in Fib(0): print f Lenard Lindstrom <[email protected]>