Lua coroutine.create

Lua coroutine.creat

相当于在C ++中使用lua_newthread(Equivalent of Lua coroutine.create in C++ using lua_newthread)

问 题

I have a callback system, which can add lua functions to a C++ handler, e.g. in lua i can do

myCObject:AddCallback(luaFunc)

i also have the same, for coroutines

myCObject:AddCallback(coroutine.create(luaFunc))

I then can use

lua_State * pThread = lua_tothread(L, -1);
lua_resume(pThread, 0,0);

in C++

To start/resume the lua function.

Now, i dont want to require script writers to write coroutine.create(luaFunc) - and i just want to automatically "convert" a lua func to a coroutine. When AddCallback gets called, i have the luaFunc on the stack - and then how do i proceed? (with coroutine.create i already have a thread on the stack)

EDIT: Im looking for a solution that uses the C API e.g. lua_newthread

解决方案

The idea is fairly simple. First, you create a new thread.

lua_State *pThread = lua_newthread(L);

This function also pushes that thread onto L. The next step is to get your thread function onto pThread. Given that you have a Lua function on the stack at this point, your next step is to transfer that function to the pThread stack.

There is a function specifically for transferring values between threads: lua_xmove. However, it only transfers the top elements of the stack. So you need to copy the Lua function from where it is on L's stack to the top of L's stack. Then lua_xmove it to the new stack.

lua_pushvalue(L, #); //Where # is the index in the stack where the function is.
                     //Remember that lua_newthread pushed a value on the stack, so compensate for that.
lua_xmove(L, pThread, 1); //Moves the function to the top of the new stack.

Remember that lua_xmove moves the value, which removes it from L. So lua_pushvalue pushes the value, and lua_xmove pops it. So the top of the stack is again the lua_State represented by pThread.

After that, push all of the parameters you need to send to the function (which apparently is zero), and resume it.

lua_resume(pThread, 0);

The total code:

lua_State *pThread = lua_newthread(L);
lua_pushvalue(L, #); //Where # is the index in the stack where the function is.
                     //Remember that lua_newthread pushed a value on the stack, so compensate for that.
lua_xmove(L, pThread, 1); //Moves the function to the top of the new stack.
lua_resume(pThread, 0);

A Lua thread (whether created in Lua or in the C API) is a Lua value, just like a table, userdata, string, etc. Therefore, it is subject to garbage collection. It will be collected when Lua detects that there are no more references to the value.

Remember: lua_newthread pushes the thread onto the original stack. It is up to you to copy it into the registry, or into the global environment or wherever you intend for that thread to permanently reside. Simply keeping a pointer to the lua_State that it generated will not ensure that the thread remains alive.

本文地址:IT屋 » Equivalent of Lua coroutine.create in C++ using lua_newthread

问 题

我有一个回调系统,可以添加lua函数到C ++处理程序,例如。 in lua我可以做



  myCObject:AddCallback(luaFunc)


我也有同样的,对于协程



  myCObject:AddCallback coroutine.create(luaFunc))


然后我可以使用



  lua_State * pThread = lua_tothread(L,-1); 
lua_resume(pThread,0,0); C ++中的




lua函数。



现在,我不想要脚本编写者写coroutine.create(luaFunc) - 我只想自动“转换”一个lua func协程。当AddCallback被调用时,我有luaFunc堆栈 - 然后我如何继续? (使用coroutine.create我已经在堆栈上有一个线程)



编辑:我寻找一个解决方案使用C API。 lua_newthread


解决方案

这个想法很简单。首先,创建一个新的线程。



  lua_State * pThread = lua_newthread 


此函数还将该线程推送到 L 。下一步是让你的线程函数到 pThread 。鉴于此时在堆栈上有一个Lua函数,下一步是将该函数传递给 pThread 堆栈。



有一个专门用于在线程之间传输值的函数: lua_xmove 。但是,它只传输堆栈的顶层元素。所以你需要将Lua函数从 L 的栈复制到 L 的顶部堆栈。然后 lua_xmove 它到新的堆栈。



  lua_pushvalue ); //其中#是函数在堆栈中的索引。 
//记住,lua_newthread在堆栈上推一个值,所以补偿。
lua_xmove(L,pThread,1); //将函数移动到新堆栈的顶部。


请记住 lua_xmove moves 该值,从 L 中删除​​它。因此, lua_pushvalue 推送值,并且 lua_xmove 弹出它。因此,堆栈的顶部再次是 pThread 表示的 lua_State 。



之后,推送所有需要发送到函数的参数(显然为零),然后恢复。



  lua_resume(pThread,0); 


总代码:



  lua_State * pThread = lua_newthread(L); 
lua_pushvalue(L,#); //其中#是函数在堆栈中的索引。
//记住,lua_newthread在堆栈上推一个值,所以补偿。
lua_xmove(L,pThread,1); //将函数移动到新堆栈的顶部。
lua_resume(pThread,0);





一个Lua线程C API)是一个Lua值,就像一个表,userdata,string等等。因此,它是受垃圾收集。



请记住: lua_newthread 将线程到原始堆栈。它是由你把它复制到注册表,或全球环境或任何你打算永久居住的线程。只要保留指向 lua_State 的指针,它就不会确保线程仍然有效。


本文地址:IT屋 » 相当于Lua coroutine.create在C ++中使用lua_newthread


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Lua 中,协程(coroutine)是一种特殊的线程,可以在执行过程中挂起和恢复。协程可以用于实现协作式多任务,允许程序在某个点上暂停,并在稍后的时间点继续执行。下面是一些常见的 Lua 协程使用方法: 1. 创建协程:使用 `coroutine.create` 函数来创建一个新的协程。 ```lua local co = coroutine.create(function() -- 协程的执行逻辑 end) ``` 2. 启动协程:使用 `coroutine.resume` 函数来启动或恢复一个协程的执行。 ```lua local success, result = coroutine.resume(co) ``` 3. 挂起协程:使用 `coroutine.yield` 函数来手动挂起一个协程的执行,并返回结果。 ```lua local function foo() print("Hello") coroutine.yield() print("World") end local co = coroutine.create(foo) coroutine.resume(co) -- 输出 "Hello" coroutine.resume(co) -- 输出 "World" ``` 4. 检查协程状态:使用 `coroutine.status` 函数来检查协程的状态。 ```lua local status = coroutine.status(co) ``` 常见的状态有: - "suspended":协程处于挂起状态,即已经创建但尚未执行或已经执行但被挂起。 - "running":当前正在执行的协程。 - "dead":协程已经执行完毕或发生错误导致终止。 以上是一些基本的协程使用方法,还可以使用 `coroutine.wrap` 函数将一个函数转换为协程。在实际应用中,协程可以用于实现状态机、异步操作、迭代器等功能。根据具体需求,可以灵活运用协程的特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值