多线程和协程

多线程是抢占式多任务(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. 安卓表格布局android:collapseColumns,android:shrinkColumns和stretchColumn

    TableLayout的行数由开发人员直接指定,即有多少个TableRow对象(或View控件),就有多少行. TableLayout的列数等于含有最多子控件的TableRow的列数.如第一Table ...

  2. BZOJ 2179 FFT快速傅里叶

    fft. #include<set> #include<map> #include<ctime> #include<queue> #include< ...

  3. linux - 开机启动thunderbird、chromium

    cd ~/.config/autostart/(没有autostart,自己 mkdir autostart) vim thunderbird.desktop,输入以下: [Desktop Entry ...

  4. JavaScript备忘录-闭包

    var arr = new Array(); function Person() { for (var i = 0; i < 10; i++) { //要记住,这个属性函数申明,只有立即执行才会 ...

  5. ASP.NET MVC模型部分验证

    在很多情况下,我们为了代码的复用可能会存在ViewModel共用的情形.比方说,web应用中常常会遇到的一个需求就是用户找回密码的功能.用户首先要验证通过验证邮箱(通常是用户名)来获取验证码,然后再进 ...

  6. 【Mysql】初学命令行指南

    MYSQL初学者使用指南与介绍 一.连接MYSQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL. 首先在打开DOS窗口,然后进入目录 mysqlbi ...

  7. Kotlin 语言高级安卓开发入门

    过去一年,使用 Kotlin 来为安卓开发的人越来越多.即使那些现在还没有使用这个语言的开发者,也会对这个语言的精髓产生共鸣,它给现在 Java 开发增加了简单并且强大的范式.Jake Wharton ...

  8. 计算时间间隔的js

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. CF 577C Vasya and Petya's Game

    题意:一个游戏,A童鞋在1~n的范围里猜一个数,B童鞋询问一个集合,A童鞋要对集合里每个数做出回答,他猜的数能否给整除,B要通过这些答案得到A猜的数,最少需要猜哪些数? 解法:一个数可以由若干个质数的 ...

  10. Android 获取本机WIFI及3G网络IP

    获取本机WIFIprivate String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemServic ...