gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 01:59:34 24 4
gpt4 key购买 nike

注意:下面有一些问题可以说明我的想法,但是我要寻找的唯一答案是标题中实际问题的答案。在这里不要求“一本书”,也不要求对所有这些都逐项答复。

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


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

在给定线程L中启动和恢复协程。

要启动协程,请将主函数加到线程堆栈上
任何论点;然后调用lua_resume,其中nargs是
论点。当协程暂停或完成其调用时,此调用返回
执行。返回时,堆栈包含所有传递给的值
lua_yield或body函数返回的所有值。 lua_resume返回
如果协程产生,则为LUA_YIELD;如果协程完成,则为LUA_OK
无错误执行,或在发生错误时显示错误代码(请参见
lua_pcall)。

如果发生错误,则不会解开堆栈,因此您可以使用调试API
超过它。该错误消息在堆栈的顶部。

要恢复协程,请从最后一个lua_yield中删除所有结果,
在其堆栈上,仅将值作为yield的结果传递,然后
呼叫lua_resume。

来自的参数代表协程的L值。
没有这样的协程,此参数可以为NULL。


在这里,“代表代表协程的L的含义”的含义非常不清楚。什么时候“ from”为nil,Lfrom中的哪个是“线程堆栈”,恢复协程的确切要求是什么?可以在初始L和第二个实际恢复的状态之间修改状态lua_resume()吗?如果是这样,状态如何知道恢复到哪里/什么功能?如果不是(即每个lua_State一个线程),创建新线程的正确方法是什么,以便它与父线程共享执行上下文(全局变量,环境等),以及调用的正确方法是什么? lua_resume()并在这种情况下取​​消每个启动/恢复的呼叫? 'from'参数可能与以下任何事物相关吗?

最后,无论哪种情况-我如何在尊重/意识到跨简历调用的错误处理程序(例如,从lua_pcall的错误中调用)中获取用于调试的完整堆栈跟踪信息? lua_getinfo()通过简历正确报告吗?那是“ from”参数的目的吗?

我真的很想从C API中启动一个协程开始/恢复的完整示例,该示例说明了第二个参数的用法。要点上有this example,但是它已经存在了多年,并且API从那时起发生了变化-lua_resume()现在需要3个参数,而不是2个...

最佳答案

当“ from”为nil时,L和from中的哪个为“线程堆栈”。


如果您要询问from参数的含义,请输入it would appear that there isn't much of one。只有在协程内部调用执行简历的C函数本身时,才可以使用它。

L是已将要恢复的参数(和启动函数,如果它是初始的resume调用)压入的堆栈。这样最适合术语“线程堆栈”。


恢复协程的确切要求是什么?


the docs for lua_status中所述,如果线程的状态为LUA_OKLUA_YIELD,则可以恢复线程。

请注意,恢复线程和恢复协程之间有区别。 lua_resume恢复线程。如果状态为LUA_OK,则没有活动协程,因此您正在创建新的协程,因此必须提供功能。如果线程是LUA_YIELD,则恢复线程将恢复产生的协程。


是否可以在初始lua_resume()和第二个实际恢复的状态之间修改状态L?


当然可以;它一定要是。毕竟,您将获得的回报/收益率值推到L上。当您继续进行恢复时,必须删除这些值并将新值作为将从Lua的yield函数返回的值压入堆栈。

是的,您可以对其进行修改。但是有关于您可以做什么的规则。他们两个人:

规则#1:你不能戳那些不属于你的东西。

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

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


F是您要启动的功能。参数1、2和3。因此,您将3作为 nargs传递。 ABC只是您放入该堆栈中的任意内容。

如果协程产生,则您的堆栈如下所示:

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


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

abc是在Lua中传递给 yield的值。您可以和他们一起玩,让您心满意足。您甚至可以通过它们的绝对堆栈索引1、2和3来返回并戳 ABC

您不能做的是更改 LOTS OF STUFF。该数据代表产生的协程状态。您无权更改。完全没有您可能也无法删除其下方的任何元素。因此,您甚至无法删除 ABC

规则2:您必须完全从堆栈中断的地方继续。

在协程生成后,您可以从堆栈中删除一些东西,然后向其中添加东西(根据规则1)。假设堆栈看起来像这样:

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


a是原始返回值之一,而其他则是您在此期间创建的临时值。因此,现在该恢复协程了。您需要传递一些新参数1和2。如何做到这一点?

您的第一步必须是清理混乱。您必须将堆栈返回到这一点:

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


完成后,您可以按1和2,然后将 nargs设为2来恢复协程。


如果是这样,状态如何知道恢复到哪里/什么功能?


上面的 LOTS OF STUFF部分告诉它“要恢复的位置/功能”。


什么是创建新线程的适当方法,以便它与父线程共享执行上下文(全局变量,环境等)


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

这些函数的执行方式(是否协程)与它们所处的环境无关。


最后,无论哪种情况-如何在尊重/意识到跨简历调用的错误处理程序(例如,从lua_pcall中对错误进行调用)中获取用于调试的完整堆栈跟踪信息?


你不能

lua_resume由于错误而失败时,它将信息留在堆栈上以跟踪简历和发出错误的位置之间发生的情况。但是它不知道简历本身是如何发生的。这是您必须执行的操作,具体取决于您如何恢复该协程。

from字段的目的不是将恢复器连接到恢复器。

关于lua - lua_resume():第二个参数的含义是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37644678/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com