Programming in Lua -- 27.2 Continuations

通过lua_pcall和lua_call可以实现,在lua脚本中调用C函数,这个C函数同时可以回调lua中的函数。标准库中有很多个函数都是这样实现的,比如table.sort可以调用排序函数;string.gsub可以调用替换函数;pcall和xpcall在保护模式下调用函数。我们是否还记得,lua的主要代码是通过C(主程序)来调用的,所以我们得到一条调用链条:C(主程序)--> Lua(脚本)--> C(库)--> Lua(回调函数)。

Lua通常可以很容易的处理这样的调用链条;毕竟和C混合使用是Lua的特点。然而,一个意外的情况是在使用coroutines(线程)的时候,这样的交错调用会碰到一些问题。

lua中的每个线程都有它自己的栈,栈中保存着等待调用的线程信息。具体的讲,栈中存放着:返回地址、参数和每次调用的局部变量。为了调用lua函数,解析器使用合适的数据结构来实现这个栈,这里称之为soft stack(软栈)。然而,为了调用C函数,同样解析器必须使用C的栈,因为返回地址、局部变量都存放在C的栈中。

解析器可以做到同时拥有多个soft stack,但是ANSI C的runtime只能有一个内部的栈(译者注:runtime同一个时间只能拥有一个栈)。因此,当一个lua线程执行C函数的时候不能被挂起:lua线程从resume到yield之间,如果调用了C函数;那么当lua线程yield的时候,lua并不能保存当前C函数的执行信息,所以当lua线程从新resume的时候,lua就不能恢复C函数的执行信息。pcall函数是一个C函数,因此lua不能将它挂起,原因是lua不能挂起ANSI C函数,并将它恢复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值