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函数,并将它恢复。

你可能感兴趣的:(Programming in Lua -- 27.2 Continuations)