<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>fleurer &#187; coroutine</title>
	<atom:link href="http://www.fleurer-lee.com/tag/coroutine/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fleurer-lee.com</link>
	<description>rage and love, story of my life.</description>
	<lastBuildDate>Thu, 02 Sep 2010 11:07:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>简介协程</title>
		<link>http://www.fleurer-lee.com/2009/07/13/%e7%ae%80%e4%bb%8b%e5%8d%8f%e7%a8%8b/</link>
		<comments>http://www.fleurer-lee.com/2009/07/13/%e7%ae%80%e4%bb%8b%e5%8d%8f%e7%a8%8b/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 11:53:20 +0000</pubDate>
		<dc:creator>ssword</dc:creator>
				<category><![CDATA[翻译]]></category>
		<category><![CDATA[coroutine]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[并发]]></category>

		<guid isPermaLink="false">http://swdpress.cn/?p=645257</guid>
		<description><![CDATA[原文：Coroutines Tutorial
翻译：ssword

What are coroutines?
何为协程？


协程允许我们同时执行多个任务。将它们分派到不同的子程序(routine)中，在每个子程序表示完成时将控制权转移，并可以回到上次完成的位置继续执行，如之重复，从而实现并发。
在参考手册的2.11节和5.2节中都有对协程的讲解。

Multi-threading
多线程


让每个任务独立地运行在一个线程中，同时执行多个任务就叫做多线程(multi-threading)。使用多线程的应用就叫做多线程应用(multi-threaded)。
多线程的实现方式多种多样，一些系统是为每个线程申请固定的时间，在时间结束时转移控制权到下一个线程。这叫做抢占式(pre-emptive)多线程。这种调度方式中，每个线程不必关心自己占据的时间，而更关注于自身的功能。
还有别的系统，线程知道自己占据的时间，也知道应自己在何时转让控制权给别的线程，来执行各自的功能。这叫做联合式(cooperative)或协作式(collaborative)多线程。应用程序中的所有线程都是协作在一起，这也正是lua协程使用的多任务方式。
Lua的协程既非操作系统线程，也非进程。它是在lua中创建的一块代码，与线程一样有自己的控制流程，不过在同一时刻只能运行一个协程。而且只有新协程被激活或有yield(返回到执行它的那个协程)，才会转移控制权。协程就是表示协作式线程的一种简单方式，不过没有并行(execute in parallel)，也就无法得到多核心CPU的性能优势。但是，由于协程在切换起来要比操作系统线程快得多，也不需要复杂甚至代价昂贵的锁机制，使用协程通常都要比等价的操作系统线程轻快一些。

Yielding


要让多个协程共同执行，就必须停止当前协程的执行(在执行一些操作之后)，并转移控制权到另一个协程，这种操作就叫做yielding。协程可以直接调用个一个lua函数，coroutine.yield()，它与函数的return类似。使用yield退出函数的位置可以被记住，在稍后可以回到该位置接着刚才的上下文继续执行。不过若使用return退出，函数的整个上下文就被销毁了，我们也就无法回到该位置。

&#62; function foo&#40;x&#41;
&#62;&#62;  if x&#62;3 then return true end  -- we can exit the function before the end if need be
&#62;&#62;  return false                 -- return a value at the end of [...]]]></description>
			<content:encoded><![CDATA[<p>原文：<a href="http://lua-users.org/wiki/CoroutinesTutorial">Coroutines Tutorial</a><br />
翻译：ssword</p>
<h3>
What are coroutines?<br />
何为协程？<br />
</h3>
<p></p>
<p>协程允许我们同时执行多个任务。将它们分派到不同的子程序(routine)中，在每个子程序表示完成时将控制权转移，并可以回到上次完成的位置继续执行，如之重复，从而实现并发。</p>
<p>在参考手册的<a href="http://www.lua.org/manual/5.1/manual.html#2.11">2.11节</a>和<a href="http://www.lua.org/manual/5.1/manual.html#5.2">5.2节中</a>都有对协程的讲解。</p>
<h3>
Multi-threading<br />
多线程<br />
</h3>
<p></p>
<p>让每个任务独立地运行在一个线程中，同时执行多个任务就叫做多线程(multi-threading)。使用多线程的应用就叫做多线程应用(multi-threaded)。</p>
<p>多线程的实现方式多种多样，一些系统是为每个线程申请固定的时间，在时间结束时转移控制权到下一个线程。这叫做抢占式(pre-emptive)多线程。这种调度方式中，每个线程不必关心自己占据的时间，而更关注于自身的功能。</p>
<p>还有别的系统，线程知道自己占据的时间，也知道应自己在何时转让控制权给别的线程，来执行各自的功能。这叫做联合式(cooperative)或协作式(collaborative)多线程。应用程序中的所有线程都是协作在一起，这也正是lua协程使用的多任务方式。</p>
<p>Lua的协程既非操作系统线程，也非进程。它是在lua中创建的一块代码，与线程一样有自己的控制流程，不过在同一时刻只能运行一个协程。而且只有新协程被激活或有yield(返回到执行它的那个协程)，才会转移控制权。协程就是表示协作式线程的一种简单方式，不过没有并行(execute in parallel)，也就无法得到多核心CPU的性能优势。但是，由于协程在切换起来要比操作系统线程快得多，也不需要复杂甚至代价昂贵的锁机制，使用协程通常都要比等价的操作系统线程轻快一些。</p>
<h3>
Yielding<br />
</h3>
<p></p>
<p>要让多个协程共同执行，就必须停止当前协程的执行(在执行一些操作之后)，并转移控制权到另一个协程，这种操作就叫做yielding。协程可以直接调用个一个lua函数，coroutine.yield()，它与函数的return类似。使用yield退出函数的位置可以被记住，在稍后可以回到该位置接着刚才的上下文继续执行。不过若使用return退出，函数的整个上下文就被销毁了，我们也就无法回到该位置。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #b1b100;">function</span> foo<span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>  <span style="color: #b1b100;">if</span> x<span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">3</span> <span style="color: #b1b100;">then</span> <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">true</span> <span style="color: #b1b100;">end</span>  <span style="color: #808080; font-style: italic;">-- we can exit the function before the end if need be</span>
<span style="color: #66cc66;">&gt;&gt;</span>  <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">false</span>                 <span style="color: #808080; font-style: italic;">-- return a value at the end of the function (optional)</span>
<span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #b1b100;">end</span>
<span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> foo<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #b1b100;">false</span>
<span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> foo<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span>                     <span style="color: #808080; font-style: italic;">-- different exit point</span>
<span style="color: #b1b100;">true</span></pre></div></div>

<h3>
Simple usage<br />
简单的用法<br />
</h3>
<p></p>
<p>要创建一个协程，得先有个表示它的函数。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #b1b100;">function</span> foo<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;foo&quot;</span>, <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">coroutine.yield</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;foo&quot;</span>, <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #b1b100;">end</span>
<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>使用coroutine.create(fn)函数可以创建一个协程，它的参数是个lua函数。它返回的类型为thread:</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> co <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coroutine.create</span><span style="color: #66cc66;">&#40;</span>foo<span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">-- create a coroutine with foo as the entry</span>
<span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">type</span><span style="color: #66cc66;">&#40;</span>co<span style="color: #66cc66;">&#41;</span>                 <span style="color: #808080; font-style: italic;">-- display the type of object &quot;co&quot;</span>
thread</pre></div></div>

<p>我们可以用coroutine.status()函数来检查线程的状态。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coroutine.status</span><span style="color: #66cc66;">&#40;</span>co<span style="color: #66cc66;">&#41;</span>
suspended</pre></div></div>

<p>状态suspended表示这个线程是可用的，而且如你所想，它还什么也没做。注意，在我们创建线程时，它不会立即执行。要执行它，我们使用corotine.resume()函数。Lua会进入这个线程，并在出现yield时离开。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coroutine.resume</span><span style="color: #66cc66;">&#40;</span>co<span style="color: #66cc66;">&#41;</span>
foo     <span style="color: #cc66cc;">1</span>
<span style="color: #b1b100;">true</span></pre></div></div>

<p>corotine.resume函数返回了resume调用的错误状态。这输出表示了我们进入的是foo函数，退出时没发生错误。有趣的地方就在这里。单靠一个函数，我们不可能回到离开时的上下文继续执行，而协程则允许我们一次次地resume：</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coroutine.resume</span><span style="color: #66cc66;">&#40;</span>co<span style="color: #66cc66;">&#41;</span>
foo     <span style="color: #cc66cc;">2</span>
<span style="color: #b1b100;">true</span></pre></div></div>

<p>可以看出，这行代码回到了foo中上次yield的位置执行并返回，没有错误发生。不过如果看下它的状态，就可以看出我们退出了foo函数，协程也结束了。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coroutine.status</span><span style="color: #66cc66;">&#40;</span>co<span style="color: #66cc66;">&#41;</span>
dead</pre></div></div>

<p>如果试图再次resume，就会返回两个值，一个错误标记和一条错误信息：</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coroutine.resume</span><span style="color: #66cc66;">&#40;</span>co<span style="color: #66cc66;">&#41;</span>
<span style="color: #b1b100;">false</span>   cannot resume dead <span style="color: #b1b100;">coroutine</span></pre></div></div>

<p>一旦协程退出，或是像函数那样返回，它就无法执行resume了。</p>
<h3>
More details<br />
</h3>
<p></p>
<p>下面是个复杂些的例子，展示协程的几个性质：</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #b1b100;">function</span> odd<span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'A: odd'</span>, x<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">coroutine.yield</span><span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'B: odd'</span>, x<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #b1b100;">end</span>
<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;</span> <span style="color: #b1b100;">function</span> even<span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'C: even'</span>, x<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">if</span> x<span style="color: #66cc66;">==</span><span style="color: #cc66cc;">2</span> <span style="color: #b1b100;">then</span> <span style="color: #b1b100;">return</span> x <span style="color: #b1b100;">end</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'D: even '</span>, x<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #b1b100;">end</span>
<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;</span> co <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coroutine.create</span><span style="color: #66cc66;">&#40;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>     <span style="color: #b1b100;">for</span> i<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">1</span>,x <span style="color: #b1b100;">do</span>
<span style="color: #66cc66;">&gt;&gt;</span>       <span style="color: #b1b100;">if</span> i<span style="color: #66cc66;">==</span><span style="color: #cc66cc;">3</span> <span style="color: #b1b100;">then</span> <span style="color: #b1b100;">coroutine.yield</span><span style="color: #66cc66;">&#40;</span>-<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">end</span>
<span style="color: #66cc66;">&gt;&gt;</span>       <span style="color: #b1b100;">if</span> i <span style="color: #66cc66;">%</span> <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">==</span> <span style="color: #cc66cc;">0</span> <span style="color: #b1b100;">then</span> even<span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">else</span> odd<span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">end</span>
<span style="color: #66cc66;">&gt;&gt;</span>     <span style="color: #b1b100;">end</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">end</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;</span> count <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>
<span style="color: #66cc66;">&gt;</span> <span style="color: #b1b100;">while</span> <span style="color: #b1b100;">coroutine.status</span><span style="color: #66cc66;">&#40;</span>co<span style="color: #66cc66;">&#41;</span> ~<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'dead'</span> <span style="color: #b1b100;">do</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'----'</span>, count<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">;</span> count <span style="color: #66cc66;">=</span> count+<span style="color: #cc66cc;">1</span>
<span style="color: #66cc66;">&gt;&gt;</span>   errorfree, value <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coroutine.resume</span><span style="color: #66cc66;">&#40;</span>co, <span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span>   <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'E: errorfree, value, status'</span>, errorfree, value, <span style="color: #b1b100;">coroutine.status</span><span style="color: #66cc66;">&#40;</span>co<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #b1b100;">end</span>
<span style="color: #808080; font-style: italic;">----    1</span>
A: odd  <span style="color: #cc66cc;">1</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    <span style="color: #cc66cc;">1</span>       suspended
<span style="color: #808080; font-style: italic;">----    2</span>
B: odd  <span style="color: #cc66cc;">1</span>
C: even <span style="color: #cc66cc;">2</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    -<span style="color: #cc66cc;">1</span>      suspended
<span style="color: #808080; font-style: italic;">----    3</span>
A: odd  <span style="color: #cc66cc;">3</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    <span style="color: #cc66cc;">3</span>       suspended
<span style="color: #808080; font-style: italic;">----    4</span>
B: odd  <span style="color: #cc66cc;">3</span>
C: even <span style="color: #cc66cc;">4</span>
D: even         <span style="color: #cc66cc;">4</span>
A: odd  <span style="color: #cc66cc;">5</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    <span style="color: #cc66cc;">5</span>       suspended
<span style="color: #808080; font-style: italic;">----    5</span>
B: odd  <span style="color: #cc66cc;">5</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    <span style="color: #b1b100;">nil</span>     dead
<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>我们有个for循环，它调用到两个函数：如果它是个奇数，就调用odd()；是偶数，则调用even()。它的输出可能有点难看，所以我们就研究下由count计数的外部循环。已经加上了注释。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">----    1</span>
A: odd  <span style="color: #cc66cc;">1</span>       <span style="color: #808080; font-style: italic;">-- yield from odd()</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    <span style="color: #cc66cc;">1</span>       suspended</pre></div></div>

<p>在循环中，我们使用coroutine.resume(co,5)来调用这个协程。第一次调用是在进入协程函数的for循环中。注意下这个odd函数，它由我们协程函数中的yield调用。协程函数中不一定非得yield，这点很重要。使用yield，我们返回1。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">----    2</span>
B: odd  <span style="color: #cc66cc;">1</span>       <span style="color: #808080; font-style: italic;">-- resume in odd with the values we left on the yield</span>
C: even <span style="color: #cc66cc;">2</span>       <span style="color: #808080; font-style: italic;">-- call even and exit prematurely</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    -<span style="color: #cc66cc;">1</span>      suspended  <span style="color: #808080; font-style: italic;">-- yield in for loop</span></pre></div></div>

<p>在第二个循环中，主循环yield并暂停了这个协程。这里的要点就是，我们可以在任何位置执行yield。我们不必纠结在协程中的一点执行yield。使用yield，我们返回-1。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">----    3</span>
A: odd  <span style="color: #cc66cc;">3</span>       <span style="color: #808080; font-style: italic;">-- odd() yields again after resuming in for loop</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    <span style="color: #cc66cc;">3</span>       suspended
We resume the <span style="color: #b1b100;">coroutine</span> <span style="color: #b1b100;">in</span> the <span style="color: #b1b100;">for</span> loop <span style="color: #b1b100;">and</span> when odd<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> is called it yields again.</pre></div></div>

<p>在for循环中，我们resume这个协程，在调用odd()时，它就再执行次yield。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">----    4</span>
B: odd  <span style="color: #cc66cc;">3</span>       <span style="color: #808080; font-style: italic;">-- resume in odd(), variable values retained</span>
C: even <span style="color: #cc66cc;">4</span>       <span style="color: #808080; font-style: italic;">-- even called()</span>
D: even <span style="color: #cc66cc;">4</span>       <span style="color: #808080; font-style: italic;">-- no return in even() this time</span>
A: odd  <span style="color: #cc66cc;">5</span>       <span style="color: #808080; font-style: italic;">-- odd() called and a yield</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    <span style="color: #cc66cc;">5</span>       suspended</pre></div></div>

<p>在第四个循环中，我们在离开时resume了odd()。注意下其中的变量都保留了，odd()函数的上下文在协程暂停时依然保留。even()函数执行到最后，我们到达了它的末尾。若使用coroutine.yield()以外的其他方式退出函数，函数的上下文及变量一律被销毁。只有使用yield才可以返回。</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">----    5</span>
B: odd  <span style="color: #cc66cc;">5</span>       <span style="color: #808080; font-style: italic;">-- odd called again</span>
E: errorfree, value, status     <span style="color: #b1b100;">true</span>    <span style="color: #b1b100;">nil</span>     dead  <span style="color: #808080; font-style: italic;">-- for loop terminates</span>
<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>再次回到odd()。这次主循环到了5，也就是协程的极限。5以及for循环的状态在协程的整个执行过程中都有保留。每个协程都有自己的栈和状态，而我们一旦退出协程函数，它就销毁了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2009/07/13/%e7%ae%80%e4%bb%8b%e5%8d%8f%e7%a8%8b/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
