fiber(cooperative multi-threading)

Michael Sparks ms at cerenity.org
Fri Dec 28 14:49:52 EST 2007


Duncan Booth wrote:

> There are also problems where full blown coroutines are appropriate. The
> example I quoted earlier of turning a parser from one which generates a
> lot of callbacks to one which 'yields' tokens is the usual example given.

For completeness, I looked at the other half of the thread at the expat
parser, and decided to write that in the style we use for Kamaelia - it
ends up looking like this:

import xml.parsers.expat
import Axon
from Kamaelia.Chassis.Pipeline import Pipeline
from Kamaelia.Util.Console import ConsoleEchoer

class Parser(Axon.ThreadedComponent.threadedcomponent):
    data = "<h1> Default </h1>"  # Can be overridden by kwargs as normal

    def start_element(self, name, attrs):
        self.send(("START", name, attrs), "outbox")

    def end_element(self, name):
        self.send(("END", name), "outbox")

    def char_data(self, data):
        data = data.strip()
        self.send(("DATA", data), "outbox")

    def main(self):
        p = xml.parsers.expat.ParserCreate()
        p.StartElementHandler = self.start_element
        p.EndElementHandler = self.end_element
        p.CharacterDataHandler = self.char_data
        p.Parse(self.data, 1)
        self.send(Axon.Ipc.producerFinished(), "signal")

Pipeline(
    Parser(data="<body><h1>Hello</h1> world <p>Woo</p></body>"),
    ConsoleEchoer(),
).run()

You'll note we don't use generators for "Parser" in this context. This also
isn't 100% identical to form you use since we don't turn this into an
iterator (obviously :).

We do also use 1 more thread than the greenlet approach though. Pipeline
& ConsoleEchoer are generator based though, as is the scheduler that
runs them :-)

Have fun :-)


Michael.
--
http://yeoldeclue.com/blog
http://kamaelia.sourceforge.net/Developers/




More information about the Python-list mailing list