对lua协程的一点理解
读《Programming In Lua》协程那一章,比较困惑的还是procuer-consumer那个例子:
function consumer(prod)while true dolocal x = receive(prod)print(x)end endfunction receive(prod)local status, value = coroutine.resume(prod)return value endfunction send(x)coroutine.yield(x) -- go back to where resumed endfunction producer()return coroutine.create(function()while true dolocal x = io.read()send(x)endend) end-- consumer-driven design consumer(producer())
producer产生数据,consumer消费数据,producer与consumer都在各自的协程中完成, 代码很短,但是很难读 - 至少不是那么一目了然,尤其比起这个直接的循环:
function produce()return io.read() endfunction consume(x)print(x) endwhile true dolocal x = produce()consume(x) end
好在哪里?
书中说可以添加缓存控制速度,或者进行数据过滤 - 但是这在循环版本的producer-consumer中也都能做到,无非在在实现produce是多些逻辑,或者再加个filter的函数处理produce的返回值,协程版本毫无优势可言。
实在要说其优点,恐怕只是:producer和consumer的代码在各自的协程中实现,并通过resume-yield交换数据 - 实现了松耦合。这是个优点,可以还是不太满意,再往下看时,看到了全排列那个例子,稍作修改,让我比较直观的感觉到了协程这种控制结构的灵活性:
function send(a)coroutine.yield(a) endfunction receive(prod)local status, value = coroutine.resume(prod)return value endfunction consumer(prod)local function print_result(a)for _, v in ipairs(a) doio.write(v, " ")endio.write('\n')endwhile true dolocal a = receive(prod)if not a then break endprint_result(a)end endfunction producer(a)function permgen(a, n)if n == 0 thensend(a) -- send something for consuming from an recursive callelsefor i=1, n doa[n], a[i] = a[i], a[n]permgen(a, n-1)a[n], a[i] = a[i], a[n]endendendlocal n = table.getn(a)return coroutine.create(function() permgen(a, n) end) endconsumer(producer({1,2,3,4}))
这里全排列采用了递归算法:对数组中的每个元素,把它交换到数组末尾,然后对前n-1个元素的子数组做同样的事,当n==0时,输出一个排列。
这个在produce的时候,因为在一个递归调用中,你无法一个个返回:
- 要么每找到一个,直接在里面处理 - 这样produce-consume的结构就有点混淆在一起;
- 或者先把结果保存在一个共享内存中,产生全部排列后,再逐个处理 - 这样要另外开辟空间,流程上感觉也不够简洁。
于是,协程的有点就显现出来了,不同于简单函数中的return,协程可以在找到一个排列后,yield挂起本协程并返回该排列,返回到原来resume这个协程的代码处,取得数据进行consume,然后继续resume进入协程获取排列 - 通过协程灵活控制流程并传递数据,十分漂亮。
所以,那个循环版本的问题是:并不是所有produce的数据,都可以简单的return回来的。
转载于:https://www.cnblogs.com/baiyanhuang/archive/2012/11/17/2775315.html
对lua协程的一点理解相关推荐
- lua协程 unity_XLua 之 Lua 协程 与 Unity 协程互通
前言: 最近在摸索用XLua 在 Unity 中进行全Lua 开发.然后就遇到了协程的问题.我想在 Lua 侧开启一个 Unity 的协程,该怎么做呢? 一开始我先去翻 XLua 的文档,我记得之前我 ...
- Lua协程Coroutine是什么
Lua协程Coroutine是什么 协程和线程不同: 同一时刻,一个多线程程序可以用多个线程同时执行:而协程只能有一个在执行 多线程是抢占式的:而协程是非抢占式的,只有协程显示被挂起,才会被挂起 协程 ...
- Unity协程实现分析以及Lua协程与Unity协程的混合使用
1,节选翻译一篇stackoverflow关于Unity协程实现的讨论 - The big clues are in the C# version. Firstly, note that the re ...
- Lua 协程和线程区别
协程就是协程,不是线程. CPU执行单位是线程,不是什么协程. 协程,是同步执行,不是并行,只是切了一个上下文了,为你保存原来的上下文而已. 切到第二个协程时,原来的协程处于挂起状态. 这个特指lua ...
- lua协程 unity_unity协程coroutine浅析
一.序言 在unity的游戏开发中,对于异步操作,有一个避免不了的操作: 协程,以前一直理解的懵懵懂懂,最近认真充电了一下,通过前辈的文章大体理解了一下,在这儿抛砖引玉写一些个人理解.当然首先给出几篇 ...
- 关于进程,线程,协程,一点心得
1:进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在当代面向线程设计的计算机结构中,进程是线程的容器,一个进程中 ...
- go 怎么等待所有的协程完成_理解真实世界中 Go 的并发 BUG
点击上方蓝色"Go语言中文网"关注,回复「电子书」领全套Go资料 有几个学生研究归纳了go编程中的并发bugs,发表了一篇(英文)论文:<Understanding Real ...
- python3 协程 写法_理解Python的协程(Coroutine)
由于GIL的存在,导致Python多线程性能甚至比单线程更糟. GIL: 全局解释器锁(英语:Global Interpreter Lock,缩写GIL),是计算机程序设计语言解释器用于同步线程的一种 ...
- LUA 协程 Coroutine
协程 Coroutine 协程(coroutine)并不是 Lua 独有的概念,如果让我用一句话概括,那么大概就是:一种能够在运行途中主动中断,并且能够从中断处恢复运行的特殊函数.(嗯,其实不是函数. ...
最新文章
- 更简单的非递归遍历二叉树的方法
- c#如何跳出一个函数_C#初学者教程系列9:类和对象
- 《高性能JavaScript》第五章 字符串和正则表达式
- DTCC 2020 | 阿里云吉剑南:在线分析进入Fast Data时代的关键技术解读
- 改变UITextField placeHolder颜色、字体
- 使用Apriori进行关联分析(二)
- 无法转化为项目财富的技术或功能就是垃圾
- python零基础学习书-零基础学习python推荐几本书?
- state 全局值 设置 和获取
- MySQL数据库简单了解
- matlab时频分析工具箱安装,Matlab emd工具箱、时频分析工具箱下载以及安装方法...
- Gitlab-Runner安装并注册
- P3376 (最大流 dinic)
- 学习AngularJs:Directive指令用法
- 生活家健康指南:创可贴使用四大误区
- 初识智遥工作流软件——表单开发篇1
- 基于可见光通信的移动机器人室内定位及物联网应用
- Virtual Machine Monitors——VMM总结
- 河边的小屋原来是这么俗气的一个名字
- RPC编程:Hessian RPC一个老的RPC框架(一)
热门文章
- Applications Manager Docker监控
- 为Tiny4412设备驱动在proc目录下添加一个可读版本信息的文件
- Undefined symbols for architecture i386:_OBJC_CLASS_$_xx, referenced from: 解决方法
- 《SQL初学者指南(第2版)》——2.4 指定列
- bind安装配置以及应用
- Linux下C++ UDP Socket例子
- Develop内部函数,持续更新
- mysql select array_从数据库select查询出来的数组
- jdbctemplate mysql 配置_Spring JDBCTemplate配置使用
- str045漏洞提权linux,Linux运维知识之CVE-2016-5195 Dirtycow: Linux内核提权漏洞