lua运行外部程序_Lua之协同程序(coroutine)

本文详细介绍了Lua中的协同程序(coroutine),包括其与线程的区别、基本语法(如coroutine.create(), coroutine.resume(), coroutine.yield()等),以及通过实例演示了如何使用协同程序解决生产者-消费者问题。理解协同程序的运作原理有助于在实际项目中利用其进行同步控制和数据传递。
摘要由CSDN通过智能技术生成

什么是协同(coroutine)?

Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。

协同是非常强大的功能,但是用起来也很复杂。

线程和协同程序区别

线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。

在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只有在明确的被要求挂起的时候才会被挂起。

协同程序有点类似同步的多线程,在等待同一个线程锁的几个线程有点类似协同。

基本语法方法描述

coroutine.create()创建coroutine,返回coroutine, 参数是一个函数,当和resume配合使用的时候就唤醒函数调用

coroutine.resume()重启coroutine,和create配合使用

coroutine.yield()挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果

coroutine.status()查看coroutine的状态

注:coroutine的状态有三种:dead,suspend,running,具体什么时候有这样的状态请参考下面的程序

coroutine.wrap()创建coroutine,返回一个函数,一旦你调用这个函数,就进入coroutine,和create功能重复

coroutine.running()返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个corouting的线程号function foo(a)

print("foo 函数输出 ",a)

-- 返回2*a的值

return coroutine.yield(2 * a)

end

co = coroutine.create(function (a,b)

--cp-body 1 10

print("第一次协同程序执行输出 ", a,b)

local r = foo(a + 1)

print("第二次协同程序输出 ",r)

--a,b的值为第一次调用协同程序时传入

local r,s = coroutine.yield(a+b, a - b)

print("第三次协同程序输出 ",r,s)

--b的值为第二次调用协同程序时传入

return b,"结束协同程序"

end)

print("---------------分割线---------------");

print("main", coroutine.resume(co,1,10))  --true 4

print("协同程序的状态: ",coroutine.status(co))

print("---------------分割线---------------");

print("main", coroutine.resume(co,"r"))  --true 4

print("协同程序的状态: ",coroutine.status(co))

print("---------------分割线---------------");

print("main", coroutine.resume(co,"x","y"))  --true 4

print("协同程序的状态: ",coroutine.status(co))

print("---------------分割线---------------");

print("main", coroutine.resume(co,"x","y"))  --true 4

print("协同程序的状态: ",coroutine.status(co))

print("---------------分割线---------------");

以上实例接下如下:调用resume,将协同程序唤醒,resume操作成功返回true,否则返回false;

协同程序运行;

运行到yield语句;

yield挂起协同程序,第一次resume返回;(注意:此处yield返回,参数是resume的参数)

第二次resume,再次唤醒协同程序;(注意:此处resume的参数中,除了第一个参数,剩下的参数将作为yield的参数)

yield返回;

协同程序继续运行;

如果使用的协同程序继续运行完成后继续调用 resume方法则输出:cannot resume dead coroutine

resume和yield的配合强大之处在于,resume处于主程中,它将外部状态(数据)传入到协同程序内部;而yield则将内部的状态(数据)返回到主程中。

=============================================================================

生产者-消费者问题

现在我就使用Lua的协同程序来完成生产者-消费者这一经典问题。local newProductor

function productor()

local i= 0;

while true do

i = i + 1;

send(i) -- 将生产的物品发给消费者

end

end

function consume()

i = 0

while (i 

do

i = i + 1

local i = receive() --从生产者那里得到物品

print(i)

end

end

function receive()

local status , value = coroutine.resume(newProductor)

return value

end

function send(x)

--x表示需要发生的值,值返回以后,就挂起该协同程序

coroutine.yield(x)

end

-- 启动程序

newProductor = coroutine.create(productor)

consume()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值