zoukankan      html  css  js  c++  java
  • lua协程一则报错解决“attempt to yield across metamethod/C-call boundary”

    问题

    attempt to yield across metamethod/C-call boundary

    需求跟如下帖子中描述一致:

    http://bbs.chinaunix.net/forum.php?mod=viewthread&action=printable&tid=4065715

    模拟一个场景,在C中创建出coroutine来执行Lua脚本,并且提供C API给Lua使用,当某些操作可能会阻塞时(如网络I/O),C函数中执行yield将协程切换出去,然后未来的某个时刻,如果条件满足则resume 继续执行后面的脚本.我写了个demo程序是这样的:

    但是使用此帖子中的 方法的, 将resume和yield都放在c中实现, 也没有解决问题。

    使用lua版本为 5.1.4

    解法

    http://stackoverflow.com/questions/8459459/lua-coroutine-error-tempt-to-yield-across-metamethod-c-call-boundary

    There are several things you can do if you cannot change your code to avoid the C/metamethod boundary:

    • If you are using standard Lua, and are compiling it yourself, try patching it with Coco — True C Coroutines for Lua.

      True C coroutine semantics mean you can yield from a coroutine across a C call boundary and resume back to it.

    • Try using LuaJIT instead of the standard Lua interpreter. It uses a fully resumable VM meaning the boundary is not an issue.

    • Try using Lua 5.2. It features yieldable pcall and metamethods which means that it can handle your problem. However, there are some changes and incompatibilities between Lua 5.1 and Lua 5.2.

    不改代码的话,有三种解法。

    第一种,  打个补丁,最简单,对现有代码影响最小。

    故使用这个方法。

    coco patch

    http://coco.luajit.org/

    Coco is a small extension to get True C Coroutine semantics for Lua 5.1. Coco is available as a patch set against the standard Lua 5.1.5 source distribution.

    Coco is also integrated into LuaJIT 1.x to allow yielding for JIT compiled functions. But note that Coco does not depend on LuaJIT and works fine with plain Lua.

    Coco is Copyright © 2004-2016 Mike Pall. Coco is free software, released under the MIT license (same license as the Lua core).

    由于其是基于5.1.5开发, 将patch移植到5.1.4版本还有一些比对工作。 如何将patch还原为old new, 可以使用前面博文介绍。

    将patch移到版本中后发现,还是不生效。

    最后确定是, c中开辟线程空间的时候, 没有使用 coco的接口, 还是使用 lua的原生接口。

    http://lua-users.org/lists/lua-l/2011-10/msg00461.html

    On 10/15/2011 5:35 PM, Szymon Gatner wrote:
    >   lua_State* coro = lua_newthread(L);
    
    You need to use lua_newcthread(). Otherwise LuaJIT 1.x doesn't create a
    C stack.
    

    http://coco.luajit.org/api.html

    lua_State *lua_newcthread(lua_State *L, int cstacksize)

    This is an (optional) new function that allows you to create a coroutine with an associated C stack directly from the C API. Other than that it works the same as lua_newthread(L).

    You have to declare this function as extern yourself, since it's not part of the official Lua API. This means that a C module that uses this call cannot be loaded with standard Lua. This may be intentional.

  • 相关阅读:
    Winform配置文件读写操作
    Winform 实现图片轮播(解决Image.FromFile内存不足)
    asm磁盘dd破坏恢复
    文件系统重新分区oracle恢复
    删除分区 oracle asm disk 恢复
    raid强制上线后数据库无法启动故障处理
    记录一次oracle现场故障处理经过
    .makop病毒加密数据库恢复
    Oracle Recovery Tools解决数据库open过程报 ORA-01555错误
    操作系统层面反删除恢复文件损坏太多处理—-oracle碎片恢复
  • 原文地址:https://www.cnblogs.com/lightsong/p/5785615.html
Copyright © 2011-2022 走看看