programming in lua 初读 12

初学者,有错误希望指正。

12————————————————协同 coroutine

#!/usr/local/bin/lua
--[[
co=coroutine.create(function()
print("hi")
end
)
]]
--[[
print(co)
print(coroutine.status(co))
coroutine.resume(co)
print(coroutine.status(co))
]]
--[[
count=1
co=coroutine.create(function()
  for i=1,10 do
    print("co",i)
    print("count",count)
    count=count+1
    coroutine.yield()
  end
end
)
for i=1,10 do
coroutine.resume(co)
print(coroutine.status(co),"status")
--print(coroutine.resume(co),"resume")
--注释掉的这句是因为没理解清楚一开始,coroutine.resume(co)会先执行再返回true或false,结果变成了两次
print("count",count)
print("lable",i)
end
]]
--[[通过resume-yield交换数据]]
--[[
--没有yield时,resume把参数传递给协调的主程序
co=coroutine.create(function(a,b,c)
print("co",a,b,c)
end
)
coroutine.resume(co,1,2,3)
]]
--[[
--数据有yield传递给resume,true表示调用成功,之后的参数是yield的参数,resume的参数会被传递给yield
--一旦协同执行,yield接收到的resume的值就无法更改(目前--疑问)
co=coroutine.create(function(a,b)
    for i=1,2 do
      print("a,b",a,b)
      print("lablein",i)
    coroutine.yield(a+b,a-b)
    end
end
)
--for i=1,10 do
  -- print("lable",i)
  -- print(coroutine.resume(co,i,1+10))
  -- print(coroutine.status(co))
  -- print("label",i)
--end
co1=co
co2=co
for i=1,2 do
 if i==1 then print(coroutine.resume(co1,30,10))
--yield确实把处理后的值传递了过来,读取了30,10进行操作
  else  print(coroutine.resume(co1,5,10)) end 
--yield不仅没有读取新的值,反而保留了原先的值   
--这之上的两条注释实在,创建co1,co2之前的,但是结果相同,所以说传值是对于coroutine来说的,一旦执行协同程序,就不再传值了
--整个协同程序函数的for循环是不会被执行的
--协同程序函数返回两个值,a,b作为resume返回值
---协同程序执行完毕时,resume的返回值就不再是yield的参数了,也就是说yield会一直固话直到结束
end
--输出结果
--a,b     30      10
--lablein 1
--true    40      20
--a,b     30      10
--lablein 2
--true    40      20
]]
--[[
--代码结束时的返回值,也会传给resume
co=coroutine.create(function()
  return 6,7
end
)
print(coroutine.resume(co))
]]
--[[lua的协同称为不对称协同,指的是挂起一个正在执行的协同函数,与使一个被挂起的协同再次执行的函数是不同的。有些语言提供对称协同,即使用同一个函数负责执行与挂起间的状态切换
严格意义上的协同不论在什么地方,只要不在其他的辅助代码内部的时候都可以并且只能使执行挂起,不论什么时候在其控制栈内都不会有不可决定的调用。
]]
--[[用coroutine解决消费者生产者问题]]
#!/usr/local/bin/lua
--[[
--用协同解决生产者消费者问题
--当一个协同调用yield时并不会进入一个新的函数,取而代之的是返回一个未决的resune的调用,相似的,调用resume时也不会开始一个新的函数而是返回yield的调用
--消费者驱动生产者
function receive()
  print("收到请求商品的请求")
  print("开始请求商品")
  local status,value=coroutine.resume(producer)
  print("获得商品",value)
  return value
end
function send(x)
  print("消费者获得商品"..x)
  print("生产者休息")
  coroutine.yield(x)
  --yield的参数返回给resume,因为从resume读入的不是固定值所以,yield的返回值不固定
end
producer=coroutine.create(function()
  while true do
   print("消费者输入想要获得产品信息")
   local x=io.read()
   print("读入完毕,开始生产商品"..x)
   print("开始发送给消费者")
   send(x)
  end
end
)
for i=1,10 do
  print("这是第"..i.."次请求")
  print("这是获得的商品"..receive())
end
]]
--[[
--recieve运行coroutine获得返回值,send使用yield返回值
--pipe,producer都是 return coroutine.create(function end)
--producer获得输入,pipe进行string.format
--使用协同实现管道
function recieve(corout)
  local status,value=coroutine.resume(corout)
  return value
end
function send(corout)
  coroutine.yield(corout)
end
--管道实现
function pipe(corout)
   local line=1
   return coroutine.create(function()
   local x=recieve(corout)
   x=string.format("%5d %s",line,x)
   line=line+1
   send(x)
   end
)
end
function producer()
    return coroutine.create(function()
    while true do
    local x=io.read()
    send(x)
    end
end) 
end
function comsumer(corout)
  local x=recieve(corout)
  io.write(x)
end
for i=1,10 do
p=producer()
--获得producer return的coroutine
p=pipe(p)
--获得pipe return的coroutine
comsumer(p)
--通过receive的resume返回pipe通过recieve的resume返回的producer通过io.read()读入并通过send使用yield返回的值
end
--执行顺序producer>>pipe>>comsumer
]]
--[[
--用coroutine实现迭代器
--[[
function permgen(a,n)
  if n==0 then
    printResult(a)
  else
    for i=1,n do
      --printResult(a)
       print(n)
      a[i],a[n]=a[n],a[i]
      --printResult(a)
      permgen(a,n-1)
      print(n)
      --不仅内部递归,还内部循环
      a[i],a[n]=a[n],a[i]
      --printResult(a)
    end
  end
end
function printResult(a)
   for i,v in ipairs(a) do
        io.write(v," ")
   end
   io.write("\n")
end
permgen({"a","b","c"},3)
]]
--将printResult用coroutine.yeild替代,返回的值再用printResult输出
--循环输出 表a
function printResult(a)
   for i,v in ipairs(a) do
        io.write(v," ")
   end
   io.write("\n")
end
--迭代器
function permgen(a,n)
  if n==0 then
    coroutine.yield(a)
  else
    for i=1,n do
      --printResult(a)
       print(n)
      a[i],a[n]=a[n],a[i]
      --printResult(a)
      permgen(a,n-1)
      print(n)
      --不仅内部递归,还内部循环
      a[i],a[n]=a[n],a[i]
      --printResult(a)
    end
  end
end
--迭代工厂 return funciton end
function perm(a)
  local n=#a
  local co=coroutine.create(function() permgen(a,n) end)
  return function()
     local code,res=coroutine.resume(co)
     return res
  end
end
for p in perm({"a","b","c"}) do
   printResult(p)
end
]]
--[[
--非抢占式多线程
--例子:通过http从远程主机上下载文件使用Luasocket库完成
--安装使用Lua扩展库LuaSocket
--因为luaosck库较新的更新在2007年,似乎不支持最新版的,重装lua为 2006-02-20 5.1版本
[root@localhost ~]# wget http://www.lua.org/ftp/lua-5.1.tar.gz
root@localhost lua]# tar xzvf  lua-5.1.tar.gz
修改配置文件config
LUAINC=-I/root/lua-5.1/src
LUALIB=-L/usr/local/lib/lua/5.1


INSTALL_TOP_SHARE=/usr/local/share/lua/5.1
INSTALL_TOP_LIB=/usr/local/lib/lua/5.1


[root@localhost luasocket-2.0]# make
[root@localhost luasocket-2.0]# make install
require "socket"  
function receive(connection)  
    connection:settimeout(0)  
    local s, status, partial = connection:receive(2^10)  
    if status == "timeout" then  
        coroutine.yield(connection)  
    end  
    return s or partial, status  
end  
  
function download(host, file)  
    local c = assert(socket.connect(host, 80))  
    local count = 0  
    c:send("GET " .. file .. " HTTP/1.0\r\n\r\n")  
    while true do  
        local s, status, partial = receive(c)  
        count = count + #(s or partial)  
        if status == "closed" then  
            break  
        end  
    end  
    c:close()  
    print(file, count)  
end  
  
threads = {} 
  
function get(host, file)  
    -- create coroutine  
    local co = coroutine.create(function ()  
        download(host, file)  
    end)  
    -- intert it in the list  
    table.insert(threads, co)  
end  
  
function dispatch()  
    local i = 1   
    local connections = {}  
    while true do  
        if threads[i] == nil then  
            if threads[1] == nil then  
                break  
            end   
            i = 1  -- restart the loop  
            connections = {}  
        end         
        local status, res = coroutine.resume(threads[i])  
        if not res then   
            table.remove(threads, i)  
        else     
            i = i + 1   
            connections[#connections + 1] = res   
            if #connections == #threads then   
                socket.select(connections)  
            end                                                                                                                      
        end         
    end             
end  
  
host = "www.w3.org"  
get(host, "/TR/html401/html40.txt")  
get(host, "/TR/2002/REC-xhtml1-20020801/xhtml1.pdf")  
get(host, "/TR/REC-html32.html")  
get(host, "/TR/2000/REC-DOM-Level-2-Core-20001113/DOM2-Core.txt")  
dispatch() -- main loop  
]]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值