[Stackless] Semantic of schedule_remove
Jeff Senn
senn at maya.com
Thu May 22 02:58:50 CEST 2008
On May 21, 2008, at 5:46 PM, Alberto Ganesh Barbati wrote:
> Jeff Senn ha scritto:
>> Hi Alberto-
>> Check the doc string for stackless.schedule_remove
>> import stackless
>> print stackless.schedule_remove.__doc__
>
> Thanks Jeff for the explanation. I believe that the doc, which I had
> read, is defective. It says "switch to the next runnable tasklet and
> remove self". However if the next runnable tasklet is self, the
> function clearly cannot perform both tasks. In this corner case, I
> find it more obvious to perform the remove rather than the
> (degenerate) schedule, but apparently what is happening is the
> opposite. All in all, you might say, the function is called
> schedule_remove()! Maybe it would be interesting to have a function
> named remove_schedule() with the opposite semantic, which is a much
> more useful behaviour IMHO. Or am I missing something obvious that
> might make such a function impossible to implement?
Well, I think it is that way only for historical reasons (from the
days when there
was not really even a scheduler and you needed someplace to pass
control to) --
you might also argue that you should be able to do:
stackless.getcurrent().remove() though, sadly, that does not work
either
(also for reasons having to do with history and the specific
implementation)...
>
>
> In any case, I believe this case should be described explicitly in
> the doc.
Yep. Probably true.
>
>
>> And then run this slightly modified example and see
>> if the behavior is more obvious to you. (Note: that
>> the "next runnable tasklet" could be yourself!
>> I suppose this boundary condition might be considered
>> a bit "astonishing".... :-)
>> -------
>> import stackless
>> def run(name):
>> print name, "start"
>> myself = stackless.getcurrent()
>> if stackless.schedule_remove() == myself:
>> print "No one else to switch to! Continuing..."
>
> The fact is that I do not want it to continue! I am using
> schedule_remove() to implement a cheap sort of blocking call without
> using a channel. In the complete example (the one I posted is just
> an excerpt, for sake of explanation) the tasklet calls
> schedule_remove() after requesting data which are going to be
> provided at a later time by the main tasklet. Once the main tasklet
> has the data available, it re-inserts the blocked tasklet in the
> runnable queue so that it can continue. If the block doesn't happen,
> I am in big trouble because the code would try to access data that
> is not yet available.
>
> Sure I can use a channel, but that approach requires an extra object
> (the channel itself) which is actually unnecessary.
Yep. I understand.
Channels are pretty cheap...
Or you can obviously work-around by making sure you have another
tasklet to pass to...
if stackless.getruncount() > 1:
# theoretically if you are using the timeout feature of
stackless.run() to
# simulate pre-emption there could be a race condition here!
# so in that case you might always want the branch below even
though it's more expensive
stackless.schedule_remove()
else:
#workaround: spawn a tasket just to remove me
def remove_it(a):
a.remove()
stackless.tasklet(remove_it)(stackless.getcurrent()).run()
Hope that helps (at least with the pragmatics!) :-)
-Jas
>
>
> Cheers,
>
> Ganesh
>
>
> _______________________________________________
> Stackless mailing list
> Stackless at stackless.com
> http://www.stackless.com/mailman/listinfo/stackless
>
More information about the Stackless
mailing list