多线程和协程

多线程是抢占式多任务(preemptive multitasking),每个子线程由操作系统来决定何时执行,由于执行时间不可预知所以多线程需要使用同步技术来避免某些问题。在单核计算机中,同一时刻只有一个线程允许运行,而在多核计算机中,同一时刻可以有多个线程同时运行(比如8核CPU就可以最多让8个线程同时运行)。

协程是协作式多任务(cooperative multitasking),它把决定权交给任务,让它们在自己认为合适的时候自愿放弃执行。协程不是多线程,无论是几核CPU,同一时刻都只会有一个协程在运行。

有意思的是主流的程序语言(如C++、Java、Pascal等)里我们很少能看到协程的身影,但是现在不少动态脚本语言(Lua、Python、Perl)却都提供了协程或与之相似的机制。

Lua本身不支持多线程的,不同线程共享一个State会出问题,但是支持协程。

Lua协程

官方文档:http://www.lua.org/manual/5.2/manual.html#6.2

最简单的示例

下面我们来看一个简单的示例:

 --创建一个协程对象, 传入的参数为该协程运行的主函数
co = coroutine.create(
function()
print("step 1")
coroutine.yield()
print("step 2")
coroutine.yield()
print("step 3")
end
) --运行协程
print(coroutine.status(co))
coroutine.resume(co)
print("main thread code 1")
--运行协程
print(coroutine.status(co))
coroutine.resume(co)
print("main thread code 2")
--运行协程
print(coroutine.status(co))
coroutine.resume(co)
print("main thread code 2") print(coroutine.status(co))

我们先看下运行的结果:

 suspended
step
main thread code
suspended
step
main thread code
suspended
step
main thread code
dead

我们可以发现,在协程中遇到coroutine.yield()时,该协程的运行会被暂停这时主线程会继续运行,直到调用coroutine.resume方法时对应的协程才会继续运行。当协程的方法运行完毕时该协程也就结束了,state为dead。

带参数和返回的协程

协程是可以带有参数和返回值的,如下:

 --创建一个协程对象, 传入的参数为该协程运行的主函数
co = coroutine.create(
function(a, b, c)
local i =
print("add", "add", "i:", i)
i =
coroutine.yield(a + b, b + c)
print("add", "sub", "i:", i)
i =
coroutine.yield(a + b, b - c)
print("sub", "sub", "i:", i)
i =
coroutine.yield(a - b, b - c)
print("i:", i)
end
) --运行协程
state, result1, result2 = coroutine.resume(co, , , )
print(state, result1, result2)
--运行协程
state, result1, result2 = coroutine.resume(co, , , )
print(state, result1, result2)
--运行协程
state, result1, result2 = coroutine.resume(co, , , )
print(state, result1, result2) coroutine.resume(co)

运行结果如下:

 add    add    i:
true
add sub i:
true
sub sub i:
true
i:

我们看看协程参数和返回值要注意的一点地方:

  1. 参数只有第一次调用时传入有效,后面调用resume传入的参数会被忽略;
  2. 返回值的第一个值为调用是否成功的一个布尔值,如果成功则后跟返回的参数,如果失败则后跟报错的信息;

Lua学习笔记(六):协程的更多相关文章

  1. python 3.x 学习笔记17(协程以及I/O模式)

    1.协程(微线程)协程是一种用户态的轻量级线程.协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈.因此: 协程能保留上一 ...

  2. Lua学习笔记4. coroutine协同程序和文件I/O、错误处理

    Lua学习笔记4. coroutine协同程序和文件I/O.错误处理 coroutine Lua 的协同程序coroutine和线程比较类似,有独立的堆栈.局部变量.独立的指针指令,同时又能共享全局变 ...

  3. python自动化开发学习 进程, 线程, 协程

    python自动化开发学习 进程, 线程, 协程   前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...

  4. Java IO学习笔记六:NIO到多路复用

    作者:Grey 原文地址:Java IO学习笔记六:NIO到多路复用 虽然NIO性能上比BIO要好,参考:Java IO学习笔记五:BIO到NIO 但是NIO也有问题,NIO服务端的示例代码中往往会包 ...

  5. [转]LUA 学习笔记

    Lua 学习笔记 入门级 一.环境配置 方式一: 1.资源下载http://www.lua.org/download.html 2.用src中的源码创建了一个工程,注释调luac.c中main函数,生 ...

  6. (zt)Lua的多任务机制——协程(coroutine)

    原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...

  7. Lua 学习笔记(一)

    Lua学习笔记 1.lua的优势 a.可扩张性     b.简单     c.高效率     d.和平台无关 2.注释 a.单行注释 --        b.多行注释 --[[  --]] 3.类型和 ...

  8. Lua学习笔记6:C++和Lua的相互调用

        曾经一直用C++写代码.话说近期刚换工作.项目组中的是cocos2dx-lua,各种被虐的非常慘啊有木有.     新建cocos2dx-lua项目.打开class能够发现,事实上就是C++项 ...

  9. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  10. Lua的多任务机制——协程(coroutine)

    并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系统来决定 ...

随机推荐

  1. sql字符串函数(转)

    计算字符串长度 len()用来计算字符串的长度 select sname ,len(sname) from student 字符串转换为大.小写 lower() 用来将一个字符串转换为小写,upper ...

  2. uvalive 4255 Guess(拓扑排序)

    算好题目,反正我没想到可以用图论做(虽然现在做的是图论专题= =) 首先是要把求每个位置上的值转化为求 “前缀和之差”,这是一个很有用的技巧 其次,由输入的(n+(n-1)+...+2+1)个符号,可 ...

  3. 通过对源代码的反向工程学习CoreData架构

    在本文开始,先给出反向工程后的结果: 不过需要注意,三个实例的指针都被同一个实例拥有,比如三个指针都位于appDelegate. 在AppDelegate类中定义了下面三个属性: @property ...

  4. linux笔试

    在对linux基本知识的归纳总结之后,这里是一份linux的测试题.希望能帮助大家复习和熟悉linux知识. 一.选择题 1.cron 后台常驻程序 (daemon) 用于:  A. 负责文件在网络中 ...

  5. 【已解决】Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8

    [问题] 折腾: [已解决]Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8 过程中,增大对应AVD的内存为2G后,结果无法启 ...

  6. xcode升级,报错 libxml/tree.h not found (Xcode4.6解决方案)

    转:http://blog.csdn.net/yangxuanlun/article/details/8639075 Xcode升级到4.6以后,他妈的,libxml/tree.h找不到了,搞了大半天 ...

  7. Zend Framework 入门(3)—错误处理

    undefined 说明脚本中一些对象没有设定 你应在在使用该对象前进行判断 例如: if(typeof(aobject) == "undefined"){   //错误处理 }

  8. Storm实战常见问题及解决方案

    该文档为实实在在的原创文档,转载请注明: http://blog.sina.com.cn/s/blog_8c243ea30101k0k1.html 类型 详细 备注 该文档是群里几个朋友在storm实 ...

  9. JTA事务管理--配置剖析

    概述    [IT168 专稿]Spring 通过AOP技术可以让我们在脱离EJB的情况下享受声明式事务的丰盛大餐,脱离Java EE应用服务器使用声明式事务的道路已经畅通无阻.但是很大部分人都还认为 ...

  10. nginx+tomcat反向代理下使用tomcat-redis-session-manager进行session共享中值得注意的一个问题

    公司目前项目使用nginx反向代理+多个tomcat进行负载均衡,之前使用ip_hash策略进行session控制.近期有考虑不再使用ip_hash策略,所以需要进行session共享. 根据项目实际 ...