加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

lua_resume():第二个参数的含义是什么?

发布时间:2020-12-15 00:15:50 所属栏目:大数据 来源:网络整理
导读:注意:下面有一些问题说明了我的想法,但我正在寻找的唯一答案是标题中实际问题的答案.这里没有要求“一本书”,也没有对所有这些书进行逐项回复. 我正在尝试从C API启动协程,让它产生,并在以后继续它(可能在从其他协同程序执行恢复之后).这是一个相当简单的用
注意:下面有一些问题说明了我的想法,但我正在寻找的唯一答案是标题中实际问题的答案.这里没有要求“一本书”,也没有对所有这些书进行逐项回复.

我正在尝试从C API启动协程,让它产生,并在以后继续它(可能在从其他协同程序执行恢复之后).这是一个相当简单的用例,但是lua_resume()的文档非常混乱:

int lua_resume (lua_State *L,lua_State *from,int nargs);

Starts and resumes a coroutine in the given thread L.

To start a coroutine,you push onto the thread stack the main function plus
any arguments; then you call lua_resume,with nargs being the number of
arguments. This call returns when the coroutine suspends or finishes its
execution. When it returns,the stack contains all values passed to
lua_yield,or all values returned by the body function. lua_resume returns
LUA_YIELD if the coroutine yields,LUA_OK if the coroutine finishes its
execution without errors,or an error code in case of errors (see
lua_pcall).

In case of errors,the stack is not unwound,so you can use the debug API
over it. The error message is on the top of the stack.

To resume a coroutine,you remove any results from the last lua_yield,put
on its stack only the values to be passed as results from yield,and then
call lua_resume.

The parameter from represents the coroutine that is resuming L. If there is
no such coroutine,this parameter can be NULL.

“代表正在恢复L的协程”的含义在这里非常不清楚.当确切地说是“来自”nil时,L和from中的哪一个是“线程堆栈”,以及恢复协程的确切要求是什么?可以在初始的lua_resume()和实际恢复的第二个之间修改状态L吗?如果是这样,国家如何知道恢复哪些/什么功能?如果不是(即每个lua_State一个线程)创建新线程的正确方法是什么,以便它与父线程共享执行上下文(全局,环境等),以及调用lua_resume的正确方法是什么( )并在这种情况下解除每个开始/恢复的呼叫? ‘from’参数可以与这些东西相关吗?

最后,在任何一种情况下 – 如何在错误处理程序中获取完整的堆栈跟踪(例如,在lua_pcall错误时调用),它尊重/知道跨越简历的调用? lua_getinfo()是否通过简历正确报告?那是’from’论证的意思吗?

我真的很喜欢C API的协程启动/恢复的完整,有效的例子,它说明了第二个参数的使用.要点上有this example,但它已经存在多年了,自那时起API发生了变化 – 现在lua_resume()接受3个参数,而不是2个…

解决方法

When exactly is “from” nil,which of L and from are the “thread stack”.

如果你问的是from参数的含义,it would appear that there isn’t much of one.如果正在执行简历的C函数本身是从协程中调用的,那么它才有效.

L是您已将参数推送到其上的堆栈(以及启动函数,如果它是初始恢复调用).所以这最适合术语“线程堆栈”.

what are the exact requirements for resuming a coroutine?

如the docs for lua_status中所述,如果线程的状态为LUA_OK或LUA_YIELD,则可以恢复线程.

请注意,恢复线程和恢复协程之间存在差异. lua_resume恢复一个帖子.如果状态为LUA_OK,则没有活动协程,因此您正在创建新的协程,因此必须提供一个函数.如果线程是LUA_YIELD,则恢复线程将恢复生成的协程.

Can the state L be modified between the initial lua_resume() and the second one which is actually resuming?

当然可以;它一定要是.毕竟,当你去恢复它时,你得到返回/屈服值.当你去恢复它时,你必须删除这些值并将新值作为将从Lua的yield函数返回的值推送到堆栈.

所以是的,你可以修改它.但是有关于你能做什么的规则.他们两个人:

规则#1:你不能捅那些不属于你的东西.

假设Lua堆栈在您的初始简历(从左到右)之前看起来像这样:

[A][B][C][F][1][2][3]

F是您要启动的功能. 1,2和3是参数.所以你传递3作为nargs. A,B和C只是放在堆栈上的任意东西.

如果协同程序产生,你的堆栈看起来像这样:

[A][B][C][LOTS OF STUFF][a][b][c]

很多STUFF表示由协程处理创建的任意数量的堆栈数据.没有办法知道那里会有多少或多少.

a,b和c是Lua中传递给yield的值.你可以随心所欲地玩它们.您甚至可以回到A,B和C处.

你不能做的是改变很多东西.该数据代表了屈服的协程状态.您不得更改它.完全没有.您可能也无法删除它下面的任何元素.所以你不能删除A,B或C.

规则#2:您必须准确恢复堆栈停止的位置.

协同程序产生后,您可以从堆栈中删除一些东西并添加内容(根据规则#1).所以我们假设堆栈看起来像这样:

[A][B][C][LOTS OF STUFF][a][Q][R][D]

a是原始返回值之一,其他内容是您在此期间创建的临时值.所以现在是恢复协程的时候了.你有一些新的参数要通过,1和2.你怎么做?

你的第一步必须是清理你的烂摊子.您必须将堆栈返回到此点:

[A][B][C][LOTS OF STUFF]

一旦完成,你可以按1和2,然后恢复coroutine,其中nargs为2.

If so,how does the state know where/what function to resume?

上面的LOTS OF STUFF部分告诉它“恢复哪里/什么功能”.

what is the proper way to create a new thread,so that it shares an execution context (globals,environment,etc) with the parent thread

“执行上下文”与线程无关.那些东西与功能有关,而不是线程.因此,如果您希望函数与其他函数共享相同的环境,那么它们应该与该函数共享相同的环境.

这些函数的执行方式(协程与否)与其环境无关.

And finally,in either case – how can I get a full stack trace for debugging in an error handler (for example invoked on error from lua_pcall) which respects / is aware of calls across resumes?

你不能.

当lua_resume由于错误而失败时,它会在堆栈上留下信息,以跟踪简历和发出错误的位置之间发生的情况.但它无法知道简历本身是如何发生的.这是你必须要做的事情,这取决于你如何重新开始那个协程开始.

from字段的目的不是将resumer连接到resume.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读