[Stackless] More questions on stackless.run()

Bin Huang bin.arthur at gmail.com
Fri Jun 14 22:29:27 CEST 2013


Hi Andrew,

As you suggested, I found thinking of stackless.run() being in an infinite
loop was helpful. So I went on to test stackless.run() in a few different
scenarios. This time, I got confused by different outputs in different
scenarios.

------------------code #1-----------------------
*import stackless

def sub_func():
     print "This is sub_func."
     stackless.schedule()

def func(channel):
     print "This is func.", channel.receive()
     stackless.tasklet(sub_func)()
     stackless.schedule()

channel = stackless.channel()
stackless.tasklet(func)(channel)
stackless.run()
channel.send("Hello world!")
print "Stackless.getruncount()=", stackless.getruncount()*
-------------------------------------------------------------
The output of code #1 is:
*This is func. Hello world!
Stackless.getruncount()= 3*


------------------code #2-----------------------
*import stackless

def sub_func():
     print "This is sub_func."
     stackless.schedule()

def func(channel):
     print "This is func.", channel.receive()
     stackless.tasklet(sub_func)()
     stackless.schedule()


channel = stackless.channel()
stackless.tasklet(func)(channel)
#stackless.run() # Note that this line is commented out.
channel.send("Hello world!")
print "Stackless.getruncount()=", stackless.getruncount()*
----------------------------------------------------
The output of code #2 is:
*This is func. Hello world!
Stackless.getruncount()= 3*

------------------code #3-----------------------
*import stackless

def sub_func():
     print "This is sub_func."
     stackless.schedule()

def func(channel):
     print "This is func.", channel.receive()
     stackless.tasklet(sub_func)()
     stackless.schedule()


channel = stackless.channel()
stackless.tasklet(func)(channel)
channel.send("Hello world!")
print "Stackless.getruncount()=", stackless.getruncount()
stackless.run()*
----------------------------------------------------
The output of code #3 is:
*This is func. Hello world!
Stackless.getruncount()= 3
This is sub_func.*


The above tests showed that, in order to schedule all tasklets to run, I
should call stackless.run() at the very end of my code. That's how code #3
was able to run tasklet 'sub_func'.

Also, if I run stackless.run() in the middle of my code (e.g., code #1), it
seems that stackless runtime is smart enough to bypass the stackless.run().
In this case, stackless.run() stopped behaving like an infinite loop. Am I
getting the points?

Third, if I don't even call stackless.run(), the stackless runtime is still
able to schedule some tasklets to run (e.g., code #2). Why is this?

Thanks again!

Bin


On Fri, Jun 14, 2013 at 11:37 AM, Andrew Francis <andrewfr_ice at yahoo.com>
wrote:
> Hi Bin:
>
> Message: 1
> Date: Wed, 12 Jun 2013 16:31:50 -0600
> From: Bin Huang <bin.arthur at gmail.com>
> To: stackless at stackless.com
> Subject: [Stackless] Difference between stackless.run() and
>     tasklet.run()?
> Message-ID:
>     <CAJkdMQYgbc3CBgh-0OgE+igrh4hkD_97EqdnB+XP38Ja55hCXg at mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
>
>
>>While I was learning the Stackless, I noticed a nuance between
>>executing two pieces of code which are very similar.
>
>>The difference between outputs is that the first code can exit from
>>while(1) loop while the second code cannot. I suspect there is a
>>difference between stackless.run() and tasklet.run() but I could not
>>find any good documentation on this. I hope someone can give me some
>>hints.
>
> stackless.run() starts the stackless scheduler. Think of stackless.run()
> being in an infinite
> loop similar to an event loop for a UI framework. Like your second
example,
> you set things
> up then actually start things executing with a stackless.run()
>
> tasklet.run() places a tasklet at the front of the runnable queue and
> schedules it (i.e., it is running)
> I would argue you use tasklet.run() if you are building some sort of
custom
> scheduler.
>
> An important note is if the main tasklet (that exists at the beginning of
> the world)
> terminates, any remaining tasklets will not be scheduled.
>
> I am going to rewrite your code to look like:
>
> def f():
>       while 1:
>               print id(stackless.current)
>              stackless.schedule()
>
> print "I am the main tasklet", id(stackless.current)
>
> t1 = stackless.tasklet(f)()
> t2 = stackless.tasklet(f)()
> t3 = stackless.tasklet(f)()
> t1.run()
> print "Main tasklet done", id(stackless.current)
>
> In the case of the first example, what happens is your programme begins
with
> a main tasklet. You
> create three additional tasklets. So far so good. You call t1.run().
> Tasklet t1 is placed to the fron tof the queue and is executed. The call
to
> stackless.schedule() causes the next tasklet to execute. Still
> things are good. Finally the main tasklet is scheduled. The main tasklet
> simply terminates. And because the main tasklet terminated, the other
> tasklets don't exit from the infinite loop.
> Rather they were not scheduled.
>
> I hope this clears things up.
>
> Cheers,
> Andrew
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.stackless.com/pipermail/stackless/attachments/20130614/49b1fd38/attachment.html>


More information about the Stackless mailing list