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