搜索
查看: 7073|回复: 8

纤程的详细讲解 更容易理解

  [复制链接]

47

主题

178

帖子

1176

积分

荣誉会员

Rank: 8Rank: 8

积分
1176
发表于 2013-6-8 01:15:36 | 显示全部楼层 |阅读模式
本帖最后由 朴实 于 2013-6-8 01:19 编辑

先说点题外话,纤程的知识自己老是容易忘,每次都要先看个半天才能用的起来。这次把知识整理了下,注释在这里了,希望对大家也能有所帮助。

原帖是qqmmcc 回复给落伍的 地址在这里 http://bbs.aardio.com/thread-2527-1-1.html, 在他的基础上做的修改。范例中的连续3个参数12感觉有点干扰自己的理解,改成这样4,9,15 这样3个不相关的数字 觉得好理解多了。


一个的参数就是另一个的返回值,就如传接力棒
  1. io.open()
  2. //io.print 这一行的代码都是先执行fiber的操作的。

  3. func = function(n){
  4.     for(i=1;n;1){
  5.         io.print("我正在循环",i)
  6.         io.print("返回协程:",fiber.yield (6)) //休眠,此函数传入参数将会作为fiber.resume()的返回值,下次调用。 fiber.yield (6) 是先带着数字6跳出纤程这段代码。
  7.     }   
  8. }

  9. var task = fiber.create(func)

  10. sleep(3000)// fibber.creat 并没有执行func函数,resume 才开始有执行。所以才会先sleep 3秒然后才显示“我正在循环 1”。

  11. //运行纤程
  12. io.print("跳出协程:",fiber.resume (task,4))//先执行task 对应的func 函数,4是传入启动函数func的参数n
  13. io.print("跳出协程:",fiber.resume (task,9))//9是传入fiber.yield的调用 也就是继续执行。 这一行的代码是把9带回到刚刚跳出纤程的地方,把第6行的代码执行完毕。
  14. io.print("跳出协程:",fiber.resume (task,15))

  15. execute("pause") //按任意键继续
  16. io.close();//关闭控制台
复制代码
回复

使用道具 举报

9

主题

462

帖子

2551

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2551
发表于 2013-6-8 09:45:09 | 显示全部楼层

把纤程理解为普通函数就行没必要搞的很复杂,要点是: [quote]在纤程函数内部可以使用 fiber.yield() 暂停。 而在纤程函数外部可以使用 fi

把纤程理解为普通函数就行没必要搞的很复杂,要点是:
在纤程函数内部可以使用 fiber.yield() 暂停。
而在纤程函数外部可以使用 fiber.resume() 继续。

用代码表示就是这样:
纤程函数 = fiber.create(

    function(){
        
        
//在函数内部随时可以用下面的语句暂停执行
        fiber.yield ()
    }   
)

//在函数外部随时可以用下面的语句恢复执行
fiber.resume( 纤程函数 )
明白了根本的、简单的道理,然后再去了解下参数和返回值。

fiber.yield() 负责中断,fiber.resume() 负责唤醒已中断的纤程。没有中断就没有唤醒,没有唤醒也就不存在中断,他们相互对立相互依存,就象打乒乓球把【参数】象球一样打给对方,你打球(传递参数)对方就叫接球(返回值),他们就这样相互踢球把【参数】踢给对方( 对方叫【返回值】 )

回复

使用道具 举报

9

主题

462

帖子

2551

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2551
发表于 2013-6-8 10:19:06 | 显示全部楼层

简单的应用,纤程可以使一个子程序(函数)暂停执行去做别的事, 例如正在循环读取数据库里的数据,每读取到一条数据就 fiber.yield () 暂停去处理数据

简单的应用,纤程可以使一个子程序(函数)暂停执行去做别的事,
例如正在循环读取数据库里的数据,每读取到一条数据就 fiber.yield () 暂停去处理数据,用代码表示就是这样
读取数据纤程函数 = fiber.create(

    function(){
        
var 数据库连接 = 打开数据库()

        
while( 数据还没读完 ){
            
            
var 一条记录 = 我使劲的的读啊()
            fiber.yield ( 一条记录 )
        }

        关闭数据库()
    }   
)

分析处理单条记录函数 =
function(){
   
   
while(
        
var 成功,一条记录;
        成功,一条记录 = fiber.resume (读取数据纤程函数);  
        成功 && 一条记录  
    ) {
        console.log(一条记录)
    }
}

可能有人会说,为什么简单的事要搞这么复杂,我直接都写到一个循环里更简单,如下:
var 数据库连接 = 打开数据库()
while( 数据还没读完 ){
   
var 一条记录 = 我使劲的的读啊()
    处理( 一条记录 )
}
关闭数据库()

其实这样说也没错,说简单一点纤程也就是做了上面相同的事而已。
但循环获取数据的代码实际上可能更多,处理的方式可能会经常变化,例如这次是要把数据打印到控制台,下次是要把数据提交到网络接口.....,使用纤程在分离到不同纤程的函数间交换执行代码的控制权,就可以把循环获取数据、与循环输出处理数据的代码逻辑分离开了,把经常变动的代码与不需要变动的代码分离开了。

点评

同意: 5.0 真棒: 5.0
继续努力: 5.0
同意: 5 真棒: 5 继续努力: 5
谢谢。  发表于 2014-7-15 14:30

评分

参与人数 1银币 +50 收起 理由
aaucn + 50 很给力!

查看全部评分

回复

使用道具 举报

7

主题

76

帖子

493

积分

二级会员

Rank: 3Rank: 3

积分
493
发表于 2013-6-8 10:54:08 | 显示全部楼层

受教了。 纤程的这个功能还是挺有用的。感觉像是在循环当中中断了循环,交给另外一个线程去执行,然后等待该线程处理完返回。

受教了。
纤程的这个功能还是挺有用的。感觉像是在循环当中中断了循环,交给另外一个线程去执行,然后等待该线程处理完返回。

点评

纤程并没有创建新的线程,实际上多个纤程都是在同一个线程里运行,纤程更象一个普通函数(能暂时中断的函数)  发表于 2013-6-8 12:29
回复

使用道具 举报

0

主题

24

帖子

132

积分

一级会员

Rank: 2

积分
132
发表于 2013-6-11 15:39:46 | 显示全部楼层

纤程是一种用来解决多任务同时又保持"线程安全"的一种折衷方案...

纤程是一种用来解决多任务同时又保持"线程安全"的一种折衷方案...
回复

使用道具 举报

0

主题

5

帖子

124

积分

一级会员

Rank: 2

积分
124
发表于 2014-6-17 07:12:07 | 显示全部楼层

受教了 这个纤程方法实际编程中很需要!

受教了 这个纤程方法实际编程中很需要!
回复

使用道具 举报

0

主题

2

帖子

16

积分

新手入门

Rank: 1

积分
16
发表于 2014-9-11 15:07:36 | 显示全部楼层

那请问纤程有没有栈,如果没有栈,退出的时候怎么保存现场环境

那请问纤程有没有栈,如果没有栈,退出的时候怎么保存现场环境
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-8-22 07:09 , Processed in 0.062500 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表