[Stackless] Select() on channels?

Richard Tew richard.m.tew at gmail.com
Fri Sep 14 20:09:57 CEST 2007


On 9/14/07, Christian Tismer <tismer at stackless.com> wrote:
> An inefficient but probably working solution is this silly idea:
>
> - For each of the n channels to be waited on, create a tasklet
>    that blocks reading on this channel.
>
> - it runs code like this after the receive:
>    - kill the other extra tasklets
>    - send the result on the multi-channel
>
> Instead of killing, also a dummy value could be sent, that tells
> the other tasklets to do no action.

I was just finished writing something like this while your reply arrived :)

Stackless is a minimal set of functionality.  I like that it just
provides a set of primitives.  To me this functionality and many of
the things discussed recently are better placed in a library or
framework which can be chosen for use over Stackless.


import stackless

def alt_receiver(resultChannel, inputChannel):
    result = inputChannel.receive()
    if resultChannel.balance == -1:
        resultChannel.send((stackless.getcurrent(), inputChannel, result))

def alt_select(*channels):
    resultChannel = stackless.channel()
    # See if anything is already waiting, and if so return it.
    for c in channels:
        if c.balance > 0:
            return c.receive()
    tasklets = []
    for inputChannel in channels:
        tasklets.append(stackless.tasklet(alt_receiver)(resultChannel,
inputChannel))
    firstTasklet, firstChannel, result = resultChannel.receive()
    for tasklet in tasklets:
        if tasklet is not firstTasklet:
            tasklet.kill()
    return firstChannel, result

c1 = stackless.channel()
c2 = stackless.channel()
c3 = stackless.channel()

def waiter(*channels):
    global c1, c2, c3
    print "waiting"
    ret = alt_select(*channels)
    print "waited", ret
    print "is c1: ", ret[0] == c1
    print "is c2: ", ret[0] == c2
    print "is c3: ", ret[0] == c3

def sender(c, v):
    print "sending", v
    c.send(v)
    print "sent"

stackless.tasklet(waiter)(c1, c2, c3)
stackless.tasklet(sender)(c2, 999)

stackless.run()

>>> stackless.run()
waiting
sending 999
sent
waited (<stackless.channel object at 0x00C12180>, 999)
is c1:  False
is c2:  True
is c3:  False
>>>

Cheers,
Richard.




More information about the Stackless mailing list