lua中的协程

标签: lua 协程
3人阅读 评论(0) 收藏 举报
分类:
协程,也叫协同式多线程,跟普通的多线程一样,一个协程就代表了一条独立的执行序列.
协程和普通多线程的区别在于:
    普通的多线程,也叫抢占式多线程,意味着线程间的调度通常是由操作系统来完成;
    而协程间的调度并不通过操作系统,而是由当前运行的协程显式的进行切换.

lua实现的协程是一种非对称式协程(asymmetric coroutine),这种协程机制需要通过两个函数来控制协程的执行,一个用于(重)调用协程,另一个用于挂起协程;
而一些其他语言中提供了一种对称式协程(symmetric coroutine),这种协程机制中只通过一个函数来切换协程的执行.

lua将所有关于协程的函数放在一个名为"coroutine"的table中,以下是主要的API介绍:

1. coroutine.create(f)
    创建一个新的协程,入参f是一个函数(该函数将作为协程的主函数),返回一个thread类型的值,表示该协程对象

2. coroutine.status(co)
    返回协程co当前的状态。
    一个协程存在4种状态:
                当协程被创建时都处于"suspended"状态(也就是说协程不会再创建时自动执行,显然这点跟普通多线程不同),除此之外,当协程主动挂起时也会处于"suspended"状态;
                当协程正在运行时,则处于"running"状态;
                当协程a唤醒协程b后,协程a就处于"normal"状态;
                当协程运行完主函数或因错误停止,则处于"dead"状态

3. coroutine.running()
    返回当前正在运行的协程对象,也就是一个thread类型的值.
    如果是在主线程中调用本函数则返回nil.

3. coroutine.resume(co [,...])
    启动或再次唤醒协程co执行.
    参数...是可选的,其含义有2种:
            首次启动协程co时,该协程会从主函数开始运行,而参数...会作为入参传递给主函数;
            再次唤醒协程co时,参数...会作为协程co中上次yield的返回值.
    从调用resume的主线程/协程的角度看,协程co在这期间的运行都发生在resume调用中,当协程co终止或挂起时,本次resume的调用才返回,返回值的情况分为3种:
            如果协程co正常终止,则返回true和主函数的返回值;
            如果协程co运行过程中调用yield挂起,则返回true和调用yield时传入的参数;
            如果协程co执行过程中发生错误,则返回false和错误消息。
    需要注意的是,resume是在保护模式下运行的,所以即便协程中发生任何错误都不会导致程序终止,而是将出错信息返回给调用者.

4. coroutine.yield(...)
    挂起当前正在运行的协程。
    参数...是可选的,这些参数都会作为resume的额外返回值。
    从调用yield的协程的角度看,所有在它挂起时发生的活动都发生在yield调用中,当唤醒该协程时,本次yield的调用才返回,返回值就是resume函数传入的参数。

5. coroutine.wrap(f)
    创建一个新的协程,入参f是一个函数(该函数将作为协程的主函数),返回一个类似resume的函数.
    wrap和create都可以用来创建协程,区别在于:
        [1]. wrap创建的协程,其句柄是隐藏的,意味着无法检查该协程的状态
        [2]. 调用wrap返回的函数时,它不是像resume工作在保护模式,这意味着协程执行时出错会导致程序终止
        [3]. 调用wrap返回的函数时,它在返回时没有像resume有第一个布尔量

6. 基于协程实现的带过滤功能"生产者-消费者"模型
   
 function send (data)
        coroutine.yield(data)
    end

    function recv (prod)
        local res,data = coroutine.resume(prod)
        return data
    end

    -- 创建一个生产者协程
    function producter ()
        return coroutine.create(function ()
            -- 循环从标准输入获取行数据
            while true do
            local data = io.read()
            send(data)
        end
        end)
    end

    -- 创建一个过滤器协程
    function filter (prod)
        return coroutine.create(function ()
            -- 循环接收生产者传递的数据,并添加行号,在转发给消费者
            for line = 1,math.huge do
            local data = recv(prod)
            data = string.format("%d %s",line,data)
            send(data)
        end
        end)
    end

    function consumer (ft)
        -- 消费者循环接收数据并打印到标准输出
        while true do
            local data = recv(ft)
            io.write(data,"\n")
        end
    end

    consumer(filter(producter()))


查看评论

lua 在unity 中的协程使用

最近尝试在unity中用上lua。 而其中必然会遇到的一个问题就是
  • maybe_xxh
  • maybe_xxh
  • 2014-04-14 15:43:24
  • 2198

明明白白lua的协程(coroutine)

协程和多线程下的线程类似:有自己的堆栈,自己的局部变量,有自己的指令指针,但是和其他协程程序共享全局变量等信息。线程和协程的主要不同在于:多处理器的情况下,概念上来说多线程是同时运行多个线程,而协程是...
  • booirror
  • booirror
  • 2014-10-05 23:07:11
  • 23837

Lua中的协程

coroutine.create - 创建协程函数 coroutine.create 用于创建一个新的协程,它只有一个以函数形式传入的参数,该函数是协程的主函数,它的代码是协程所需执行的内容 co =...
  • Q838352961
  • Q838352961
  • 2015-11-11 17:29:27
  • 431

lua学习笔记13:协程详解和举例

一、coroutine.create创建协程 参数是协程的主函数,返回一个thread对象 co = coroutine.create(function() print("coroutine e...
  • xufeng0991
  • xufeng0991
  • 2014-10-08 16:10:40
  • 2012

【深入Lua】理解Lua中最强大的特性-coroutine(协程)

http://my.oschina.net/wangxuanyihaha/blog/186401 coroutine基础 Lua所支持的协程全称被称作协同式多线程(collabor...
  • sharemyfree
  • sharemyfree
  • 2015-08-12 11:42:42
  • 8447

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

    并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制。大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系...
  • soloist
  • soloist
  • 2005-03-24 22:37:00
  • 33911

Lua协程(一)

Lua协程(一) 本文主要涉及Lua协程是如何工作的,并不涉及具体
  • corfox_liu
  • corfox_liu
  • 2016-03-31 14:07:35
  • 1591

浅谈Lua的Coroutine-协程的多"线程"并发模型

看了一下《Programming in Lua》里的协程程序的运用,总觉得有点像雾里看花一样,捉不到重点,不知道怎么去运用,但在洗澡时灵光一闪,突然想明白了这不只是使用了Reactor(反应时同步时间...
  • CDAmber
  • CDAmber
  • 2017-06-09 10:00:49
  • 399

[Unity3D]Lua中使用协程coroutine和计时器timer

习惯了unity3d的协程用法,那么我们在Unity里面怎么使用:
  • chiuan
  • chiuan
  • 2014-08-22 23:57:46
  • 10946

Lua的线程和状态 及协程

luaL_loadstring(L, "return coroutine.create(function() end)");   nCallResult = lua_pcall(L, 0, 1, 0...
  • linuxheik
  • linuxheik
  • 2017-04-11 14:12:15
  • 491
    个人资料
    持之以恒
    等级:
    访问量: 3万+
    积分: 910
    排名: 5万+