zoukankan      html  css  js  c++  java
  • Lua 学习笔记(九)协同程序(线程thread)

         协同程序与线程thread差不多,也就是一条执行序列,拥有自己独立的栈、局部变量和命令指针,同时又与其他协同程序共享全局变量和其他大部分东西。从概念上讲线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。也就是说多个协同程序在任意时刻只能运行一个协同程序,只有当正在运行的协同程序显式的要求挂起时,它的执行才会暂停。

     
    一、协同程序coroutine
     
         Lua将所有关于协同程序的函数放置在一个名为“coroutine”的table中。
         1、coroutine.create创建一个thread类型的值表示新的协同程序,返回一个协同程序。
         2、coroutine.status检查协同程序的状态(挂起suspended、运行running、死亡dead、正常normal)。
         3、coroutine.resume启动或再次启动一个协同程序,并将其状态由挂起改为运行。
         4、coroutine.yield让一个协同程序挂起。
         5、coroutine.wrap同样创建一个新的协同程序,返回一个函数。
     
         创建协同程序:create函数,接受一个函数值作为协同程序的执行内容,并返回一个协同程序。
     
     
         启动或再次启动一个协同程序:resume函数,接受一个协同程序及一个或多个参数用于值传递给协同程序。
     
     
         挂起协同程序:yield函数,让一个协同程序挂起,并等待下次恢复它的运行。它可以接受resume函数传递进来的所有参数。
     
     
         关于wrap函数的使用,wrap函数比create函数更易使用。它提供了一个对于协同程序编程实际所需的功能,即一个可以唤醒协同程序的函数。但也缺乏灵活性。无法检查wrap所创建的协同程序的状态,此外,也无法检测出运行时的错误。
     
     
         各种协同状态的演示:
     
     
         首先,Lua提供的是一种:”非对称的协同程序“。也就是说,Lua提供了两个函数来控制协同程序的执行,一个用于挂起执行,另一个用于恢复执行。而一些其他的语言则提供了”对称的协同程序“,其中只有一个函数用于转让协同程序之间的执行权。
     
    二、管道与过滤器filter
     
         关于协同程序的示例就是”生产者--消费者“的问题。其中涉及到两个函数,一个函数不断的产生值,另一个函数不断的消费这些值。当消费者需要一个新的值时,它唤醒生产者。生产者返回一个新值后停止运行,等待消费者的再次唤醒。这种设计称为”消费者驱动“。通过resume—yield 函数之间的值交换可以轻易的实现程序。
     
         过滤器filter,是一种位于生产者与消费者之间的处理功能,可以进行数据转换。它既是消费者又是生产者,它唤醒生产者促使其生产新值,然后又将变换后的值传递给消费者。
     
     1 --管道与过滤器filter
     2 --生产者与消费者通过过滤器进行值传递
     3 --这种模式通过消费者驱动生产者进行产生。
     4 
     5 --计数器函数
     6 function getCount( x )
     7      return function()
     8           x=x+1
     9           return x
    10      end
    11 end
    12 --创建闭合计数器
    13 local count = getCount(0)
    14 --发送新值
    15 function send(x)
    16      coroutine.yield(x)
    17 end
    18 --启动一个协同程序
    19 function receive( pro )
    20      local status,value = coroutine.resume( pro )
    21      return value
    22 end
    23 --生产者
    24 function producter()
    25      while true do
    26           send( count() )
    27      end
    28 end
    29 --过滤器,接受一个生产者
    30 function filter( pro )
    31      local x = 0
    32      return function()
    33           while true do
    34                x = receive( pro )
    35                send(x)
    36           end
    37      end
    38 end
    39 --消费者,接受一个生产者协同程序及控制条件,控制条件防止死循环
    40 --假设有100个消费者,驱动生产者来生产
    41 function consumer( pro,num )
    42      local x = 0
    43      while x < num do
    44           x = receive( pro )
    45           print( x )
    46      end
    47 end
    48 
    49 local pro = coroutine.create( producter )
    50 local fil = coroutine.create( filter( pro ) )
    51 consumer( fil,100 )
    52 
    53 print( "消费者协同程序状态:",coroutine.status(pro) )
    54 print( "生产者协同程序状态:",coroutine.status(fil) )

     
     
    三、协同程序实现的迭代器
     
         通过“生产者—消费者”模型可以很轻松的创建迭代器,同样是通过协同程序来进行控制。
     
    --以协同程序实现Lua迭代器
    
    local tab = { 1,2,3,4,5,6 }
    
    function corFun( tab,num )
         num = num or 0
         return function()
              while true do
                   num = num +1
                   if( num > #tab ) then return end
                   coroutine.yield(tab[num])
              end
         end
    end
    
    function cor( tab )
         local cor = coroutine.create( corFun( tab ) )
         return function ()--迭代器
              local status,value = coroutine.resume( cor )
              return value
         end
    end
    
    for v in cor( tab ) do
         if v then
              print(v)
         else
              break
         end
    end

     
  • 相关阅读:
    巨蟒django之权限9:前端展示修改删除合并&&权限展示
    巨蟒django之权限8:排序&&菜单展开权限归属
    巨蟒django之权限7:动态生成一级&&二级菜单
    巨蟒django之权限6: 权限控制表设计&&登录权限
    巨蟒django之CRM5 学习记录&&课程记录&&班级管理&&私户的数量上限
    巨蟒django之CRM4 一些小功能
    巨蟒django之CRM3 添加和编辑客户&&公户和私户的展示和转换
    巨蟒django之CRM2 展示客户列表&&分页
    巨蟒django之CRM1 需求分析&&表结构设计&&注册登录验证
    sysfs接口函数到建立_DEVICE_ATTR
  • 原文地址:https://www.cnblogs.com/Richard-Core/p/4373582.html
Copyright © 2011-2022 走看看